I have a number of shared variable x,y,z, all of which can modified in two different methods running in two different threads.(say method 1 in thread 1 and method 2 in thread 2) . If I declare these two methods as synchronized , does it guarantee the consistency of the variables x,y and z. Or should I separately use a lock on each of those variables?
4 Answers
Yes, your approach will guarantee consistency, assuming those variables are all private and are not accessed (read or write) outside of the two synchronized methods.
Note that if you read those variables outside of a synchronized block then you could get inconsistent results:
class Foo {
private int x;
public synchronized void foo() {
x = 1;
}
public synchronized void bar() {
x = 2;
}
public boolean baz() {
int a = x;
int b = x;
// Unsafe! x could have been modified by another thread between the two reads
// That means this method could sometimes return false
return a == b;
}
}
EDIT: Updated to address your comment about the static variable.
Each class should own its own data. If class A allows direct access to a variable (by making it public) then it is not owning its own data and it becomes very difficult to enforce thread safety.
If you do this:
class A {
private static int whatever;
public static synchronized int getWhatever() {
return whatever;
}
public static synchronized void setWhatever(int newWhatever) {
whatever = newWhatever;
}
}
then you'll be fine.
Remember that synchronized enforces a mutex on a single object. For synchronized methods it's this (or the Class object for static methods). Synchronized blocks on other objects will not interfere.
class A {
public synchronized void doSomething() {...}
}
class B {
public synchronized void doSomethingElse() {...}
}
A call to doSomething will not wait for calls to doSomethingElse because they're synchronized on different objects: in this case, the relevant instance of A and the relevant instance of B. Similarly, two calls to doSomething on different instances of A will not interfere.
I highly recommend that you take a look at Java Concurrency in Practice. It is an excellent book that explains all the subtleties of the Java thread and memory models.
7 Comments
x is an instance variable, so if there are different instances of Foo then they each have their own x. There's no need to worry about thread safety if each object is accessed by exactly one thread.Yes it will be consistent.
A synchronized method acquires a monitor (§17.1) before it executes. For a class (static) method, the monitor associated with the Class object for the method's class is used. For an instance method, the monitor associated with this (the object for which the method was invoked) is used.
Check out this link
Note:- One point you have to be careful about (several programmers generally fall in that trap) is that there is no link between synchronized static methods and sync'ed non static methods
3 Comments
This is subjective. The behaviour depends on the way you instantiate your threads. If two threads call the synchtonized methods on the same instance of the class containing these methods, they will block. If each thread instantiates a new object of the class containing the methods, they will not block since there will be two locks on two different instances of the class.
11 Comments
synchronized keyword obtains the monitor for an object. If a method is declared synchronized then it implicitly obtains the monitor for this for the duration of the method. It's perfectly acceptable to have a synchronized block that obtains the monitor for a different variable.synchronized is well-defined in the language spec, and how you obtain the Thread objects is irrelevant. If two threads access different objects then there is no way there can be a race condition or an invalid read. So we only need to consider the case where two threads access the same object. So long as critical sections (i.e. reads/writes to shared data) are protected by synchronization on an appropriate object there will not be a problem.
synchronizedis applied on instances not methods.synchronized (this)around the body of the method.