When we say we lock on an object using the synchronized keyword, does it mean we are acquiring a lock on the whole object or only at the code that exists in the block?
In the following example listOne.add
is synchronized, does it mean if another thread accesses listOne.get
it would be blocked until the first thread gets out of this block? What if a second thread accesses the listTwo.get
or listTwo.add
methods on the instance variables of the same object when the first thread is still in the synchronized block?
List<String> listONe = new ArrayList<String>();
List<String> listTwo = new ArrayList<String>();
/* ... ... ... */
synchronized(this) {
listOne.add(something);
}
Given the methods:
public void a(String s) {
synchronized(this) {
listOne.add(s);
}
}
public void b(String s) {
synchronized(this) {
listTwo.add(s);
}
}
public void c(String s) {
listOne.add(s);
}
public void d(String s) {
synchronized(listOne) {
listOne.add(s);
}
}
You can not call a and b at the same time, as they are locked on the same lock. You can however call a and c at the same time (with multiple threads obviously) as they are not locked on the same lock. This can lead to trouble with listOne.
You can also call a and d at the same time, as d is no different in this context from c. It does not use the same lock.
It is important that you always lock listOne with the same lock, and allow no access to it without a lock. If listOne and listTwo are somehow related and sometimes need updates at the same time / atomically you'd need one lock for access to both of them. Otherwise 2 separate locks may be better.
Of course, you'd probably use the relatively new java.util.concurrent classes if all you need is a concurrent list :)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With