Reputation: 82
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?
Upvotes: 1
Views: 209
Reputation: 54516
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.
Upvotes: 2
Reputation: 15212
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.
Upvotes: 0
Reputation: 5187
When you synchronize on methods :
static
, the lock will be taken on the class
objectnon-static
, the lock will be taken on the instance
object.As long as the lock is taken only by one thread at one time, yes it is consistent and safe to do what you intend to.
Upvotes: 1
Reputation: 172608
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
Upvotes: 1