I'm studying Threads in Java, and it make me curious about how to control synchronize access between static and instanc开发者_如何学Ce methods of class, since synchronization of static methods in a class is independent from the synchronization of instance methods on objects of the class.
At the moment, I can't find any situation in real life, so I make a assumption :
Two class A and B, class A have static methods with a formal parameter of class B, and instance methods do too. Then I create two threads to execute concurrently two methods of A.
How many ways to keep the state of the below obj is always consistent ?
class B { ... }
class A {
public synchronized void instanceMethod(B obj){ ... };
public static synchronized void staticMethod(B obj){ ... };
public static void main(String[] args){
B obj = new B();
// create a Thread to modify the state of obj with A's instanceMethod
// create a Thread to modify the state of obj with A's staticMethod
}
}
A static method for A cannot alter the this
state of an object A so you don't have a problem there.
A non-static method can modify a static field. However if you avoid doing this, and only use static methods to modify static fields, you can synchronized each method and it will work correctly.
It doesn't make sense to lock on one object and modify an unrelated object. If you are going to modify B, its methods should be synchronized and you might not need to have synchronized methods on A.
Can you write a clearer example which would compile?
class B {
public synchronized alter() { };
}
class A {
public void instanceMethod(B obj){ obj.alter(); };
public static void staticMethod(B obj){ obj.alter(); };
public static void main(String[] args){
B obj = new B();
// create a Thread to modify the state of obj with A's instanceMethod
// create a Thread to modify the state of obj with A's staticMethod
obj.alter();
}
}
Synchronize over the concurrent object "B".
public void instanceMethod(B obj) {
synchronized(obj) {
//no other thread will enter a synchronized block on 'obj' since we leave it
...
obj.doSomething();
...
obj.doSomethingElse(); //I can trust here that no other thread manipulated 'obj' since 2 lines before.
...
}
}
Same for the static method.
synchronize on a static lock object instead of synchronizing the method calls. This puts extra bookkeeping responsibility on you if you want to introduce other methods synchronizing with these methods: grab the lock for them as well.
class B { ... }
class A {
static Object myLock = new Object();
public void instanceMethod(B obj){ synchronized(myLock) {...} };
public static void staticMethod(B obj){ synchronized(myLock) {...} };
public static void main(String[] args){
B obj = new B();
// create a Thread to modify the state of obj with A's instanceMethod
// create a Thread to modify the state of obj with A's staticMethod
}
}
It sounds like you're worried about the state of B obj... Instead of synchronizing the methods of A, have the instance methods of B do the proper locking internally to each instance of B. Otherwise there could be a class C, that doesn't follow the locking rules and you'd wind up in an inconsistent state again.
精彩评论