Ex 1)
public void addName(String name) {
synchronized(this) {
lastName = name;
nameCount++;
}
nameList.add(name);
}
Ex 2)
public class MsLunch {
private long c1 = 0;
private long c2 = 0;
private Object lock1 = new Object();
private Object lock2 = new Object();
public void inc1() {
synchronized(lock1) {
c1++;
}
}
public void inc2() {
synchronized(lock2) {
c2++;
}
}
}
I got these two java code from java website but I don’t clearly see the difference between these two. Could you guys give more explanation which case I should use this interchangeably ? Thanks in advance
There are two differences:
thisinstead of a private reference. I view this as a bad idea in general – it means other code could also lock on the same monitor, which makes it harder to reason about your code. Unless you want other code to be able to acquire a lock on the same monitor (in which case I’d usually expose a monitor explicitly for that purpose), why put yourself at the mercy of other code? The lock should be an implementation detail in most cases, but making it a public reference (whichthisis effectively) makes that implementation detail visible to the world.inc1andinc2concurrently. If there were multiple methods in the first example, all locking onthis, then only one thread could enter any of those methods at a time.I typically use a single lock for everything within a single class unless I have good reason to believe that there are going to be lots of independent operations working on only part of the state of the class – in which case that suggests the class may be too big to start with.
I also make my “lock variables” final, as you pretty much never want to be able to change them during the lifetime of an object.
So if I really wanted to use locks, I’d probably end up writing the second example as:
However, I’d also consider:
AtomicLonginstead of locking. Often using a higher-level concept instead of threading primitives can make your code simpler to understand and more efficient.