Reputation: 7957
In the following example
Here is the sample code illustrating my questions:
BadDesign.java
public final class BadDesign{
private static int sensitiveData;
public synchronized static void changeDataViaStaticMethod(int a){
//... updating the sensitiveData
sensitiveData = a;
}
public synchronized void changeDataViaNonStaticMethod(int b){
//... updating the sensitiveData
sensitiveData = b;
}
public static void showSensitiveDataStatic(){
System.out.println("Static: " + Thread.currentThread().getName()+ " - " + sensitiveData);
}
public void showSensitiveData(){
System.out.println(Thread.currentThread().getName() + " - " + sensitiveData);
}
public static void main(String[] args){
new Thread(new TestThread11()).start();
new Thread(new TestThread11()).start();
}
}
And TestThread11.java
class TestThread11 implements Runnable{
public void run(){
int i = 0;
do{
BadDesign.changeDataViaStaticMethod(5);
BadDesign.showSensitiveDataStatic();
//... new object for every iteration
//... so synchronization of non-static method
//... doesn't really do anything significant here
BadDesign bd = new BadDesign();
bd.changeDataViaNonStaticMethod(10);
bd.showSensitiveData();
}while (i++ < 100);
}
}
Upvotes: 4
Views: 1325
Reputation: 3436
There is no problem with the do-while loop, as
BadDesign.changeDataViaStaticMethod(5); //needs BadDesign Class lock.
BadDesign.showSensitiveDataStatic(); //does not need any lock
and
bd.changeDataViaNonStaticMethod(10); // needs lock for bd object.
bd.showSensitiveData(); //does not need any lock
I hope that answers your questions.
Upvotes: 2
Reputation: 27614
I'm assuming this is coursework of some kind. It seems the point of this particular problem is to highlight two fundamental basics in Java
synchronized
implicitly uses the current object instance as lockPoint 1 is a lot about understanding what a monitor is. I invite you to study the relevant section of the Java language specification, Threads and Locks. A monitor is something that a thread can lock and unlock. When one threads locks it, any other thread attempting to lock that specific monitor will wait (block) until the first thread unlocks it.
Point 2 is about a compiler feature in Java. When you specify something as synchronized
without explicitly indicating which monitor to use, Java will use the instance of the object being called. If, however, the method is static, it will use the instance of the objects class (java.lang.Class
) as monitor. What does this mean in reality? Since there is only one unique, global, instance of each class object in a classloader context, a static method will only have one monitor. In contrast, an instance method will use the instance of the object being called as monitor so each object will have it's own monitor. Static methods are synchrionized globally, instance method are synchronized for each specific instance of the class.
Upvotes: 1
Reputation: 1502306
The non-static version will allow two different threads to come in via different objects, acquire different locks and still access the same shared data. Fundamentally, that's not thread-safe, and basically makes the locks useless. You want any piece of shared data to be covered by one lock.
You can still use non-static methods if you really want to (e.g. if the result should be determined partly by instance data as well) but you should access the shared data via a shared lock, e.g.
private static final Object staticLock = new Object();
...
synchronized (staticLock)
{
// Read or write static data
}
Upvotes: 6