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() {

假设我的java代码中有两个同步方法:

    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
请求锁放在对象实例上。