Variable in itself does not stand on its own. It needs a class to have some context. That's why the lock is on the class or the object and not on the variable.
Why is the synchronize keyword restricted to non primitive fields only?
-
05-07-2023 - |
質問
In java there is a synchronize
keyword that is used to avoid multiple thread access to a method or some block of code at some point.
My question is why can’t the synchronize
keyword be used with primitive variables? I know that java does not permit this. But what is the logic as to why this isn’t permitted since all variables in java are Object
s including primitive types like int
,float
etc.
e.g.
int a=1;
synchronized(a){}//why is this forbidden
解決
他のヒント
I suppose by variable, you meant class fields. But this is not how synchronization works in Java.
The aim of synchronized
block or method is to prevent multiple threads changing the state of a class variable at the same time. Synchronization in Java
works by owning a lock - if you have synchronized method, you are using an intrinsic lock of the object, otherwise you have to supply a lock. If fields were to be declared as synchronized
, that would more or less force all the methods in that class that uses the field to work in a synchronized way by owning the lock and this would be bad for performance.
If you are looking for synchronization guarantees at field level without having to synchronize methods, consider using Atomic variables like java.util.concurrent.atomic.AtomicInteger
You can synchronize a variable too.
synchronized(myvariable) {
.......
}
Also you should check the 'volatile' keyword. http://en.wikipedia.org/wiki/Volatile_variable#In_Java
you mean to say you need to synchronize operations on variable ? like you want to protect operation on variable e.g. increment,decrement ? java has atomic API like java.util.concurrent.AtomicBoolean
etc..
Benefits of using Atomic Concurrency classes is that we don’t need to worry about synchronization at each and every place we are dealing with integers and it’s assumed to be more efficient that synchronization which involves locking resources.
Restriction to use reference-typed objects as synchronized(..)
argument comes from the idea of encapsulation, when you and only you control who and how can access your lock
(ref or value).
Imagine the case when you want to take a lock on value-typed (primitive) lock int x = 5
, then inside synchronized
block another lock on int y = 0
. In the same time other part of your project (or 3-rd party library) also takes these locks in opposite order - first int a = 0
, then int b = 5
.
Result? Deadlock. Why? Because of lack of encapsulation - you can't control visibility of value-typed (primitive) variables. They always are public, by nature.