如果我在同一个类中有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()吗?
关于同步方法的“Java™教程”:
首先,对同一对象的同步方法的两次调用不可能交织。当一个线程正在为一个对象执行同步方法时,所有为同一对象调用同步方法的其他线程将暂停执行,直到第一个线程处理完该对象。
关于同步块的“Java™教程”:
Synchronized statements are also useful for improving concurrency with fine-grained synchronization. Suppose, for example, class MsLunch has two instance fields, c1 and c2, that are never used together. All updates of these fields must be synchronized, but there's no reason to prevent an update of c1 from being interleaved with an update of c2 — and doing so reduces concurrency by creating unnecessary blocking. Instead of using synchronized methods or otherwise using the lock associated with this, we create two objects solely to provide locks.
(强调我的)
假设你有两个不交叉的变量。所以你想同时从不同的线程访问每一个。你不需要在对象类本身上定义锁,而是在类object上定义锁,如下所示(示例来自第二个Oracle链接):
public class MsLunch {
private long c1 = 0;
private long c2 = 0;
private Object lock1 = new Object();
private Object lock2 = new Object();
public void inc1() {
synchronized(lock1) {
c1++;
}
}
public void inc2() {
synchronized(lock2) {
c2++;
}
}
}
从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()。