Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Thread.sleep vs Monitor.Wait vs RegisteredWaitHandle?

(the following items has different goals , but im interesting knowing how they "PAUSEd")

questions

Thread.sleep - Does it impact performance on a system ?does it tie up a thread with its wait ?

what about Monitor.Wait ? what is the difference in the way they "wait"? do they tie up a thread with their wait ?

what about RegisteredWaitHandle ? This method accepts a delegate that is executed when a wait handle is signaled. While it’s waiting, it doesn’t tie up a thread.

so some thread are paused and can be woken by a delegate , while others just wait ? spin ?

can someone please make things clearer ?

edit

http://www.albahari.com/threading/part2.aspx

enter image description here

like image 996
Royi Namir Avatar asked Jul 08 '12 08:07

Royi Namir


People also ask

What is the difference between thread sleep and wait?

Sleep() method belongs to Thread class. Wait() method releases lock during Synchronization. Sleep() method does not release the lock on object during Synchronization. Wait() should be called only from Synchronized context.

What is difference between wait () and sleep ()?

Difference between wait() and sleep() The major difference is that wait() releases the lock while sleep() doesn't release any lock while waiting. wait() is used for inter-thread communication while sleep() is used to introduce a pause on execution, generally.

When to Use wait and sleep in Java?

In Java, wait and sleep are the concept of multithreading. Wait and Sleep are the methods used to pause a process for few seconds and go a thread in the waiting state, respectively.

What is a sleeping thread?

Thread. sleep causes the current thread to suspend execution for a specified period. This is an efficient means of making processor time available to the other threads of an application or other applications that might be running on a computer system.


3 Answers

Both Thread.Sleep and Monitor.Wait put the thread in the WaitSleepJoin state:

WaitSleepJoin: The thread is blocked. This could be the result of calling Thread::Sleep or Thread::Join, of requesting a lock — for example, by calling Monitor::Enter or Monitor::Wait — or of waiting on a thread synchronization object such as ManualResetEvent.

RegisteredWaitHandle is obtained by calling RegisterWaitForSingleObject and passing a WaitHandle. Generally all descendants of this class use blocking mechanisms, so calling Wait will again put the thread in WaitSleepJoin (e.g. AutoResetEvent).

Here's another quote from MSDN:

The RegisterWaitForSingleObject method checks the current state of the specified object's WaitHandle. If the object's state is unsignaled, the method registers a wait operation. The wait operation is performed by a thread from the thread pool. The delegate is executed by a worker thread when the object's state becomes signaled or the time-out interval elapses.

So a thread in the pool does wait for the signal.

like image 92
Tudor Avatar answered Sep 20 '22 15:09

Tudor


Regarding ThreadPool.RegisterWaitForSingleObject, this does not tie up a thread per registration (pooled or otherwise). You can test this easily: run the following script in LINQPad which calls that method 20,000 times:

static ManualResetEvent _starter = new ManualResetEvent (false);

void Main()
{
    var regs = Enumerable.Range (0, 20000)
        .Select (_ => ThreadPool.RegisterWaitForSingleObject (_starter, Go, "Some Data", -1, true))
        .ToArray();

    Thread.Sleep (5000);
    Console.WriteLine ("Signaling worker...");
    _starter.Set();
    Console.ReadLine();

    foreach (var reg in regs) reg.Unregister (_starter);
}

public static void Go (object data, bool timedOut)
{
    Console.WriteLine ("Started - " + data);
    // Perform task...
}

If that code tied up 20,000 threads for the duration of the 5-second "wait", it couldn't possibly work.

Edit - in response to:

"this is a proof. but is there still a single thread which checks for signals only ? in the thread pool ?"

This is an implementation detail. Yes, it could be implemented with a single thread that offloads the callbacks to the managed thread pool, although there's no guarantee of this. Wait handles are ultimately managed by operating system, which will most likely trigger the callbacks, too. It might use one thread (or a small number of threads) in its internal implementation. Or with interrupts, it might not block a single thread. It might even vary according to the operating system version. This is an implementation detail that's of no real relevance to us.

like image 21
Joe Albahari Avatar answered Sep 20 '22 15:09

Joe Albahari


While it's true RegisterWaitForSingleObject creates wait threads, not every call creates one.

From MSDN:

New wait threads are created automatically when required

From Raymond Chen's blog:

...instead of costing a whole thread, it costs something closer to (but not exactly) 1/64 of a thread

So using RegisterWaitForSingleObject is generally preferable to creating your own wait threads.

like image 42
Eli Arbel Avatar answered Sep 16 '22 15:09

Eli Arbel