Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it OK to use a string as a lock object?

I need to make a critical section in an area on the basis of a finite set of strings. I want the lock to be shared for the same string instance, (somewhat similar to String.Intern approach).

I am considering the following implementation:

public class Foo {     private readonly string _s;     private static readonly HashSet<string> _locks = new HashSet<string>();      public Foo(string s)     {         _s = s;         _locks.Add(s);     }      public void LockMethod()     {         lock(_locks.Single(l => l == _s))         {             ...         }     } } 

Are there any problems with this approach? Is it OK to lock on a string object in this way, and are there any thread safety issues in using the HashSet<string>?

Is it better to, for example, create a Dictionary<string, object> that creates a new lock object for each string instance?


Final Implementation

Based on the suggestions I went with the following implementation:

public class Foo {     private readonly string _s;     private static readonly ConcurrentDictionary<string, object> _locks = new ConcurrentDictionary<string, object>();      public Foo(string s)     {         _s = s;     }      public void LockMethod()     {         lock(_locks.GetOrAdd(_s, _ => new object()))         {             ...         }     } } 
like image 933
Zaid Masud Avatar asked Oct 09 '12 17:10

Zaid Masud


People also ask

Does a lock block thread?

Locks will block other threads from executing the code contained in the lock block. The threads will have to wait until the thread inside the lock block has completed and the lock is released. This does have a negative impact on performance in a multithreaded environment.

What do you mean by locking of objects?

An object-level lock is a mechanism when we want to synchronize a non-static method or non-static code block such that only one thread will be able to execute the code block on a given instance of the class. If a thread wants to execute a synchronized method on the given object.

What is lock in thread?

A lock may be a tool for controlling access to a shared resource by multiple threads. Commonly, a lock provides exclusive access to a shared resource: just one thread at a time can acquire the lock and everyone accesses to the shared resource requires that the lock be acquired first.

Can a thread acquire multiple locks?

With locking, deadlock happens when threads acquire multiple locks at the same time, and two threads end up blocked while holding locks that they are each waiting for the other to release. The monitor pattern unfortunately makes this fairly easy to do. Here's an example.


1 Answers

Locking on strings is discouraged, the main reason is that (because of string-interning) some other code could lock on the same string instance without you knowing this. Creating a potential for deadlock situations.

Now this is probably a far fetched scenario in most concrete situations. It's more a general rule for libraries.

But on the other hand, what is the perceived benefit of strings?

So, point for point:

Are there any problems with this approach?

Yes, but mostly theoretical.

Is it OK to lock on a string object in this way, and are there any thread safety issues in using the HashSet?

The HashSet<> is not involved in the thread-safety as long as the threads only read concurrently.

Is it better to, for example, create a Dictionary that creates a new lock object for each string instance?

Yes. Just to be on the safe side. In a large system the main aim for avoiding deadlock is to keep the lock-objects as local and private as possible. Only a limited amount of code should be able to access them.

like image 193
Henk Holterman Avatar answered Sep 23 '22 05:09

Henk Holterman