简体   繁体   English

Java同步:如果将Java中的多个方法设为原子/同步,那么是否同时将锁定应用于所有这些方法?

[英]Java synchronization: If more than one methods in java are made atomic/synchronized, is the lock applied to all of them at the same time?

Suppose there are 2 synchronized methods in my java code: 假设我的Java代码中有2个同步方法:

    public class SynchronizedCounter {
    private int c = 0;

    public synchronized void increment() {
        c++;
    }

    public synchronized void decrement() {
        c--;
    }

    public synchronized int value() {
        return c;
    }
}

Suppose i have 2 operating threads: t1 and t2. 假设我有2个操作线程:t1和t2。 If t1 is operating on increment() method and goes to sleep midway, t2 won't be able to operate on increment() method because of locking. 如果t1正在使用increment()方法并中途进入睡眠状态,则由于锁定,t2将无法在increment()方法上进行操作。 My question is will t2 be able to operate on decrement() and value(), or all the synchronized methods associated with an object gets locked as soon as a thread accesses one of the synchronized methods? 我的问题是t2能够对decrement()和value()进行操作,还是与某个对象关联的所有同步方法在线程访问其中一个同步方法后立即被锁定?

What about static synchronized methods? 静态同步方法呢?

A synchronized instance method uses the object instance as the lock. 同步实例方法将对象实例用作锁。 No two threads can enter these methods with the same object at the same time. 没有两个线程可以同时使用相同的对象输入这些方法。 if your t1 and t2 are operating on the same object, t2 will be blocked until t1 releases the lock. 如果t1和t2在同一对象上操作,则t2将被阻止,直到t1释放锁定。

For static synchronized methods the lock is put on the Class object for the class the methods are contained in. 对于静态同步方法,将锁放置在包含方法的类的Class对象上。

You can read more about locking in the concurrency tutorial , but essentially the difference between static and non-static methods is the object which is locked; 您可以在并发教程中阅读有关锁定的更多信息,但是本质上来说,静态方法和非静态方法之间的区别是被锁定的对象。 the method declarations in this class: 此类中的方法声明:

class Test {
  synchronized void methodA() { ... }
  static synchronized void methodB() { ... }
}

are equivalent to the method declarations here: 等效于此处的方法声明:

class Test {
  void methodA() { 
    synchronized (this) {
        ...
    }
  }
  static void methodB() { 
    synchronized (Test.class) {
        ...
    }
  }
}

文档动作指出:“当一个线程正在执行对象的同步方法时,所有其他线程调用同一对象的同步方法(挂起执行),直到第一个线程完成该对象为止。”你的问题。

当您将一个方法声明为已同步时,该实例对象将被视为锁。

Synchronized methods operate on the lock of the instance of the class they're in. So in short: if t1 sleeps in increment() no thread can access any synchronized method. 同步方法在它们所在的类的实例的锁上进行操作。因此,简而言之:如果t1睡在increment()任何线程都无法访问任何synchronized方法。

also your code snipped is identically to the example in the Java tutorials , which also provides your answer... 此外,您所截取的代码与Java教程中的示例相同,该示例也提供了答案...

All synchronized instance methods of an object share the same lock, embodied by the object. 对象的所有同步实例方法共享由该对象实现的相同锁。 All static synchronized methods share the same lock, embodied by the class object. 所有静态同步方法共享相同的锁,由类对象实现。

If you need more fine-grained locking, you need to use a synchronized block and separate lock objects, ie 如果需要更细粒度的锁定,则需要使用同步块和单独的锁定对象,即

private Object decrementLock = new Object();
public void decrement() {
    synchronized(decrementLock){
        c--;
    }
}

Of course, in this case this would defeat the point of synchronization and lead to corrupt data. 当然,在这种情况下,这将使同步失败,并导致数据损坏。

Locks are associated with the objects not with threads. 锁与对象关联,而不与线程关联。 More than 1 threads can access the synchronized method but the objects invokes the methods should be different. 超过1个线程可以访问同步方法,但是调用方法的对象应该不同。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM