如果我在同一个类中有2个同步方法,但是每个方法访问不同的变量,2个线程可以同时访问这2个方法吗?锁是发生在对象上,还是与同步方法中的变量一样特定?
例子:
class X {
private int a;
private int b;
public synchronized void addA(){
a++;
}
public synchronized void addB(){
b++;
}
}
两个线程可以同时访问类X的同一个实例,执行x.a da()和x.a bbb()吗?
从oracle文档链接
使方法同步有两个效果:
First, it is not possible for two invocations of synchronized methods on the same object to interleave. When one thread is executing a synchronized method for an object, all other threads that invoke synchronized methods for the same object block (suspend execution) until the first thread is done with the object.
Second, when a synchronized method exits, it automatically establishes a happens-before relationship with any subsequent invocation of a synchronized method for the same object. This guarantees that changes to the state of the object are visible to all threads
看看这个文档页,了解内在锁和锁的行为。
这将回答您的问题:在同一个对象x上,当其中一个同步方法正在执行时,您不能同时调用x.a da()和x.a dbb()。
如果你有一些方法没有同步,并且正在访问和改变实例变量。在你的例子中:
private int a;
private int b;
当其他线程处于同一对象的同步方法中时,任何数量的线程都可以同时访问这些非同步方法,并可以对实例变量进行更改。
例如:
public void changeState() {
a++;
b++;
}
您需要避免出现非同步方法访问实例变量并对其进行更改的情况,否则就没有使用同步方法的意义。
在以下场景中:-
class X {
private int a;
private int b;
public synchronized void addA(){
a++;
}
public synchronized void addB(){
b++;
}
public void changeState() {
a++;
b++;
}
}
只有一个线程可以在addA或addB方法,但同时任何数量的线程都可以进入changeState方法。没有两个线程可以同时进入addA和addB(因为对象级锁定),但同时任何数量的线程都可以进入changeState。