Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Lock() in a static method

Tags:

c#

locking

I have a multi threaded application that writes to a settings xml file using a static method. I want to avoid that the file is being updated twice at the same time (causing accesss/write exception).

How do I do that?

This doesn't work:

namespace Program
{
    public class Settings
    {
        private static void SetSettingsValue (string settings, string value)
        {
            // make this thread safe to avoid writing to a locked settings xml file
            lock (typeof(Settings))
            {
                //write data to xml file
            }
        }
    }
}
like image 929
koen Avatar asked Oct 24 '10 21:10

koen


People also ask

What is a static lock?

Static-locking, or a static-lock, was a type of locking mechanism. It was typically only used when transporting tibanna gas. It would seal the tibanna cylinders from the inside.

Can a static method can acquire the lock of an instance variable?

Locks In Synchronized Methods You might wonder what happens when a static synchronized method is invoked, since a static method is associated with a class, not an object. In this case, the thread acquires the intrinsic lock for the Class object associated with the class.

Should lock object be static in Java?

As a rule of thumb, you want the lock-object to have the same static -ness than the operated-on value. So if you manipulate non-static values only, you'll want a non-static lock object. If you manipulate static values only, you'll want a static lock object.

Why we use lock 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.


2 Answers

You should create a separate, static lock object and use that. DO NOT USE A STRING! Strings are automatically interned and there will be only one instance of each programmatically declared string so you can't guarantee exclusive access to the lock.

You should do this:

public class A {
    private static Object LOCK = new Object();

    private static void foo() {
        lock(LOCK) {
            // Do whatever
        }
    }
}

(The syntax may be incorrect; I'm a Java person mostly but the same rules about locking and String interning apply to C#)

The lock keyword enforces a mutual exclusion lock: only one thread can lock any particular object at a time. If a second thread calls foo then it will block until the first thread has exited the lock block.

Take home messages: for a static method lock on a private static variable. Don't lock on Strings or typeof(...) because you cannot guarantee that no-one else is using that object. Always lock on an object you know is not touched by anyone else by making it private and making it new.

like image 165
Cameron Skinner Avatar answered Oct 19 '22 20:10

Cameron Skinner


The concept of lock() is to use an existing-object it can reference and use to control whether access is granted.

static object SpinLock = new object();

lock(SpinLock)
{
   //Statements
}

When the execution leaves the lock() block the reference is released and any other threads waiting to execute the code block can proceed (one at a time, of course).

like image 38
Erik Noren Avatar answered Oct 19 '22 19:10

Erik Noren