Why does the lock object have to be static?
It isn't "very common to use a private static readonly object for locking in multi threading" - rather, it is common to use a lock at the appropriate / chosen granularity. Sometimes that is static
. More often, IMO, it isn't - but is instance based.
The main time you see a static
lock is for a global cache, or for deferred loading of global data / singletons. And in the latter, there are better ways of doing it anyway.
So it really depends: how is Locker
used in your scenario? Is it protecting something that is itself static? If so, the lock should be static. If it is protecting something that is instance based, then IMO the lock should also be instance based.
Why does the lock object have to be readonly?
If I want to be sure that it will be locked for all threads inside my
application:
The lock object has to be static, if it locks access to static state.
Otherwise it has to be instance, because there's no need to lock state of one class instance, and prevent other threads to work with another class instance at the same time.
everyone says that the object has to be "readonly" I didn't found the
reason
Well, it doesn't have to be. This is just a best practice, which helps you to avoid errors.
Consider this code:
class MyClass
{
private object myLock = new object();
private int state;
public void Method1()
{
lock (myLock)
{
state = // ...
}
}
public void Method2()
{
myLock = new object();
lock (myLock)
{
state = // ...
}
}
}
Here Thread1 can acquire lock via Method1
, but Thread2, which is going to execute Method2
, will ignore this lock, because lock object was changed => the state can be corrupted.
Does a static lock object need to be final when using a synchronized(lock object) block?
Using the final
in this context is only a good practice.
You can synchronize using any object, final
or non final, static
or non static.
Using together final
and static
will give you the security that nobody will synchronize the same code on a different lock. Without using the final
you are not sure that somewhere in the code that variable is not reassigned.
Generally speaking using final
for a variable that is never reassigned after inited it's a good programming practice. It improves readability because who reads your code knows that this variable will never been reassigned also without reading the full code.
Do lock objects in Java need to be static?
Depends on in which context they are to be used. If you want a per-instance lock, then leave static
away. If you want a per-class lock, then use static
. Further indeed keep it final
.
C# lock a private static object
So if it's a static object, instead of a string, will it have the problem when the same method is called multiple times
Not exactly. Strings are special, they can be interned. You can't control their visibility like that of other objects.
The basic guidelines:
- keep your lockObject in a close 1-on-1 relationship with the protected resource. In numbers, scope and lifetime. So use a static lockObject to protect static data.
- keep the lockObject as private as possible, exposing it increases the risk of deadlocks. For that reason also avoid locking on Types and strings.
because it's the same static object so they are actually sharing the lock?
All code that accesses a shared resource has to share (lock on) the same lockObject instance. A private lock won't work.
Lock on non-static method
Locking on a static object in a non-static method is fine. The static object just means that there is one single lock for all your instances of the type.
If you use a class level field you have one lock per instance of your type.
Which one you choose depends on what resource you are protecting from concurrent access. For example if you have a static resource (say, a collection) then the lock protecting that resource must also be static.
Difference between lock(this) and a lock on static object
There could be a big difference. The biggest difference between the two is that the first example uses a single object to lock on (hence the static
keyword) while the this
keyword in the second example implies locking on an instance. There could therefore be a big difference from a performance perspective and even from a correctness perspective, but that depends on the code inside the lock.
When all you need is to synchronize access to instance level fields, you should not use the static
keyword, since that will synchronize the code itself, instead of the data (which could cause an unneeded performance hit). Of course, if the data itself is static (class level data instead of instance level data), you need to use the static
keyword. On the other hand, when you use the this
keyword to lock, while you're accessing shared / static resources, you will (of course) have a correctness problem, since synchronization is on an instance basis and multiple instance will still be able to access the shared data at the same time.
And there is another problem, but the difference is much smaller than for the previously noted differences. The first example uses a privately declared object to lock on, while the other uses the this
pointer, which is the reference to the object of that instance method itself. Because this reference is publicly accessible to other objects, it is possible for them to lock on it, which could cause deadlocks in rare circumstances. If you're an application developer, I wouldn't worry to much about this (as long as you don't lock on things like System.String
or System.Type
), but if you are a framework developer, you should certainly not use lock(this)
, since there is no way to tell in what way application developers will (ab)use your code.
Related Topics
ASP.NET Urlencode Ampersand for Use in Query String
Async Network Operations Never Finish
How to Change Time in Datetime
Programmatically Add an Application to Windows Firewall
How to Implement Recaptcha for ASP.NET MVC
How to Read the Data in a Wav File to an Array
Explicitly Cast Generic Type Parameters to Any Interface
C# Static Variables - Scope and Persistence
Formatting a Double to Two Decimal Places
How to Create a Custom Messagebox
How to Access Openxml Content by Page Number
How to Urlencode Without Using System.Web
How to Check If Any Flags of a Flag Combination Are Set
C# Filestream:Optimal Buffer Size for Writing Large Files
How Does Comparison Operator Works with Null Int