Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to lock on a method content

I have a method that can be called from many threads, but I just want the 1st thread to do some logic inside the method. So, I'm planning to use a boolean variable. The first thread that comes in, will set the boolean variable to false (to prevent further threads to come inside), and execute the method logic.

Subsequent threads that come to this method, will check the boolean variable. Because it was set to false by the 1st thread, they will skip the method logic.

In code, something like this:

private void myMethod()
{
   if (firsTime)  //set to true in the constructor
   {
      firstTime = false; //To prevent other thread to come inside here.
      //method logic
   }
}

I want to use lock to perform this, but not sure where to put it.

If I lock inside the "if" to change firstTime to false, its possible 2 or more threads already come inside the if (don't want this).

If I lock outside the "if" to change firstTime to false, how can the 1st thread go inside the if to execute the method logic, if firstTime its already set to false??

My question is : how to do the lock to have the desired functionality? (1st thread that comes set the boolean and execute method logic).

I cannot lock over all the method logic, since it will be a very long time consuming operations.

like image 944
user2232787 Avatar asked Aug 09 '13 16:08

user2232787


People also ask

How do you lock a method in C#?

The lock statement acquires the mutual-exclusion lock for a given object, executes a statement block, and then releases the lock. While a lock is held, the thread that holds the lock can again acquire and release the lock. Any other thread is blocked from acquiring the lock and waits until the lock is released.

Does synchronized method lock whole object?

Locks In Synchronized Methods In this case, the thread acquires the intrinsic lock for the Class object associated with the class. Thus access to class's static fields is controlled by a lock that's distinct from the lock for any instance of the class.

What does a threading lock do?

A lock allows you to force multiple threads to access a resource one at a time, rather than all of them trying to access the resource simultaneously. As you note, usually you do want threads to execute simultaneously.

How can a thread own the lock of an object?

Thread acquires the intrinsic lock when it enters a synchronized method. Thread inside the synchronized method is set as the owner of the lock and is in RUNNABLE state. Any thread that attempts to enter the locked method becomes BLOCKED.


1 Answers

You can use Interlocked.Exchange to solve this problem. It will set the value of the given variable to the specified value and return the value that used to be in the variable, and it will do it all atomically. Doing this will ensure that only one thread will ever run the code in the if:

private static int isFirst = 1;
public static void Foo()
{
    if (Interlocked.Exchange(ref isFirst, 0) == 1)
    {
        //DoStuff
    }
}

Note that Interlocked.Exchange has no overload that takes a bool, which is why you're forced to use an int (or some other type) instead, using 1 for true and 0 for false.

If you want a solution using lock, rather than Interlocked, you can do it through the use of an additional local bool value:

private static bool isFirst = true;
private static object key = new object();
public static void Foo()
{
    bool amFirst;
    lock (key)
    {
        amFirst = isFirst;
        isFirst = false;
    }

    if (amFirst)
    {
        //DoStuff
    }
}
like image 195
Servy Avatar answered Oct 19 '22 07:10

Servy