Java同步:如果Java中有多个方法是原子/同步的,那么锁是否同时应用于所有方法?
假设我的java代码中有两个同步方法:Java同步:如果Java中有多个方法是原子/同步的,那么锁是否同时应用于所有方法?,java,multithreading,synchronization,Java,Multithreading,Synchronization,假设我的java代码中有两个同步方法: public class SynchronizedCounter { private int c = 0; public synchronized void increment() { c++; } public synchronized void decrement() { c--; } public synchronized int value() {
public class SynchronizedCounter {
private int c = 0;
public synchronized void increment() {
c++;
}
public synchronized void decrement() {
c--;
}
public synchronized int value() {
return c;
}
}
假设我有两个操作线程:t1和t2。
如果t1正在对increment()方法进行操作,并且中途进入睡眠状态,则t2将无法对increment()方法进行操作,因为锁定。我的问题是t2是否能够对decrement()和value()进行操作,或者当线程访问其中一个同步方法时,与对象关联的所有同步方法都会被锁定
静态同步方法如何?同步实例方法使用对象实例作为锁。没有两个线程可以同时使用同一对象进入这些方法。如果t1和t2在同一对象上运行,t2将被阻止,直到t1释放锁为止 对于静态同步方法,该锁位于方法所包含的类的
Class
对象上
您可以在中阅读更多关于锁定的内容,但静态方法和非静态方法的本质区别在于被锁定的对象;此类中的方法声明:
class Test {
synchronized void methodA() { ... }
static synchronized void methodB() { ... }
}
与此处的方法声明等效:
class Test {
void methodA() {
synchronized (this) {
...
}
}
static void methodB() {
synchronized (Test.class) {
...
}
}
}
当您将一个方法声明为已同步时,实例对象将被视为锁。同步方法对它们所在类的实例的锁进行操作。所以简而言之:如果
t1
在increment()中休眠,则没有线程可以访问任何同步的方法
此外,您的代码被截取与中的示例相同,该示例也提供了您的答案…状态:“当一个线程正在为一个对象执行同步方法时,调用同一对象块的同步方法的所有其他线程(暂停执行),直到第一个线程对该对象执行完毕。”,这基本上回答了您的问题。一个对象的所有同步实例方法共享同一个锁,由该对象实现。所有静态同步方法共享相同的锁,由类对象实现
如果需要更细粒度的锁定,则需要使用同步块和单独的锁定对象,即
private Object decrementLock = new Object();
public void decrement() {
synchronized(decrementLock){
c--;
}
}
当然,在这种情况下,这将破坏同步点并导致数据损坏。锁与对象关联,而不是与线程关联。超过1个线程可以访问同步方法,但调用方法的对象应该不同 在您的情况下,只有方法被锁定。我想在现实生活中你会想锁定c对象。你能对静态同步方法有更多的了解吗?假设我的代码中有一个方法是静态同步的(比如value()),t1在对其进行操作时处于休眠状态,那么t2将能够对非静态方法进行操作(因为t1使用类锁而不是对象实例)?在这种情况下,t2
不会被阻止,因为锁在不同的对象上:t1
将锁放在类
对象上,t2
请求锁放在对象实例上。