Dikla
Dikla

Reputation: 3491

Is it recommended to sleep() during the operation of a very intensive thread?

I have a Java program with a blocking queue that is being populated very quickly. There are several threads that take objects from the queue and process them.

Because the new objects are generated quickly, the consuming threads don't get a chance to wait for the queue to contain an object, there is always an object waiting.

Is it recommended/needed to sleep() inside the loop of the consuming threads in order to let other processes on the machine get CPU time?

If not, because OS is taking care of time-sharing, how does it happen that a system becomes unresponsive or very slow when intensive processes are running on it?

Clarification

I'm asking about other processes on the system, not about the other threads of the Java program.

Upvotes: 0

Views: 141

Answers (3)

Deepanshu J bedi
Deepanshu J bedi

Reputation: 1540

lets take an example. this is a program where 3 threads will work simultaneously. Maybe this can clarify your problem.

class Thread1 implements Runnable
{

    int x=10;
    public void run()
    {
        for (int i = 1 ; i<=12 ; i++)
        {
            try
            {
                Thread.sleep(1000);
            } 
            catch(Exception e)
            {
            }
            System.out.println(Thread.currentThread().getName());
        }
    }
}

class Thread2 implements Runnable
{

    int x=10;
    public void run()
    {
        for (int i = 1 ; i<=10; i++)
        {
            try
            {
                Thread.sleep(1000);
            }
            catch(Exception e)
            {
            }

            System.out.println(Thread.currentThread().getName()+"count"+ i);
        }
    }
}

class Thread3 implements Runnable
{

    int x;
    public void run()
    {
        for (int i = 1 ; i<=15; i++)
        {
            try
            {
                Thread.sleep(1000);
            }
            catch(Exception e)
            {
            }

            System.out.println(Thread.currentThread().getName());
        }
    }
}

class Run
{
    public static void main(String args[])
    {
        Thread3 t1 = new Thread3();
        t1.x=50;

        Thread tt1 = new Thread(t1,"thread1");
        tt1.start();
        Thread3 t2 = new Thread3();
        t2.x=100;
        Thread tt2 = new Thread(t2,"thread2");
        tt2.start();

        System.out.println(t2.x );
        for(int i=1 ;i<=20;i++)
        {
            System.out.println(Thread.currentThread().getName());

            try
            {
                Thread.sleep(1000);
            }
            catch (Exception e)
            {
            }
        }
    }

}

here the the time sharing is managed by the os. as per the priorities the os shares its ram,processing power

how does it happen that a system becomes unresponsive or very slow when intensive processes are running on it?

open your task manager and click on details it will show you how the ram is distributed among the different apps and threads. The os decides which process to do first and the priority level is defined so that the processor can work on it.

Upvotes: 0

meriton
meriton

Reputation: 70574

Is it recommended/needed to sleep() inside the loop of the consuming threads in order to let other processes on the machine get CPU time?

Modern operating systems employ preemptive multitasking, so the other processes will be given access to resources (CPU, memory, I/O bandwidth, ...).

However, the operating system may allocate too little resources to these other processes, slowing them down. The cleanest way to prevent this is to instruct the scheduler to give priority to other processes, by setting the priority of your process appropriately (see Cross-platform way to change java process priority). Alternatively, it may be sufficient to set Thread priorities for the consumer threads (and throttle the producer thread by using a blocking, size-limited queue).

In contrast, Thead.sleep would pause your thread even if there is CPU available, wasting CPU cycles. It is also worth noting that Thread.sleep has a certain overhead, in particular if it causes a context switch. Therefore, overly frequent invocation of Thread.sleep may be very wasteful.

Therefore, Thread.sleep is a sub-optimal way to prevent resource starvation of other processes.

Upvotes: 3

DThought
DThought

Reputation: 1314

You're main problem are other processes that become unresponsive due to the workload present on the computer.

You could try to alter the priority of the java process with "nice" and/or "ionice" (for unix-related operating systems...)

This is a OS level question.

I would avoid to fix a "problem" thats on a clearly different layer by an hack like sleeping...


Theory about interprocess-locking does not apply to this question:

A better solution than sleep() and polling is to wait on some semaphore or lock.

I.e. have some monitor object, let the producer notify on that, and let the consumer wait on it.

   Object dataReady=new Object();

   //Producer:
   synchronized (dataReady) { dataReady.notify(); }

   //Consumer:
   synchronized (dataReady) { dataReady.wait();}

as noted, you're using a blocking queue. This already manages this low level multithreading synchronization stuff

//in the consumer, simply:
work=blockingQueue.take();

it will automatically wait (using the mechanism described above, or something equivalent) until one producer did put() a product in the queue

Upvotes: 1

Related Questions