简体   繁体   English

从另一个同步方法调用同步方法是否安全?

[英]Is it safe to call a synchronized method from another synchronized method?

If a synchronized method calls another synchronized method, is it thread safe? 如果synchronized方法调用另一个synchronized方法,它是否是线程安全的?

void synchronized method1() {
     method2()
}

void synchronized method2() {
}

Yes, when you mark methods as synchronized , then you are really doing this: 是的,当您将方法标记为已synchronized ,您实际上是这样做的:

void method1() {
    synchronized (this) {
        method2()
    }
}

void method2() {
    synchronized (this) {
    }
}

When the thread call gets into method2 from method1, then it will ensure that it holds the lock to this , which it will already, and then it can pass through. 当线程调用进入从方法1方法2,那么它会确保它持有锁到this ,它已经将,然后它可以通过。

When the thread gets directly into method1 or method2, then it will block until it can get the lock ( this ), and then it will enter. 当线程直接进入method1或method2时,它将阻塞直到它可以获得锁( this ),然后它将进入。

As noted by James Black in the comments, you do have to be aware with what you do inside of the method body. 正如James Black在评论中所指出的那样,你必须要了解你在方法体内所做的事情。

private final List<T> data = new ArrayList<T>();

public synchronized void method1() {
    for (T item : data) {
        // ..
    }
}

public void method3() {
    data.clear();
}

Suddenly it's not thread safe because you are looking at a ConcurrentModificationException in your future because method3 is unsynchronized, and thus could be called by Thread A while Thread B is working in method1 . 突然,因为你正在寻找一个它不是线程安全的ConcurrentModificationException在你的未来,因为method3是不同步的,因此可以通过线程A,而线程B在工作被称为method1

Is a method marked with synchronized call another synchronized method thread safe. 是一个标有同步调用方法的另一个同步方法线程安全。

In general, it is not possible to say. 一般来说,不可能说。 It depends on what the methods do, and what other methods on the same and other classes do. 这取决于方法的作用,以及相同和其他类的其他方法。

However, we can be sure that calls to method1 and method2 on the same object made by different threads will not execute simultaneously. 但是,我们可以确保不同线程对同一对象的method1和method2的调用不会同时执行。 Depending on what the methods do, this may be sufficient to say that the class is thread-safe with respect to these methods. 根据方法的作用,这可能足以说该类对于这些方法是线程安全的。

From the Java Tutorials site http://download.oracle.com/javase/tutorial/essential/concurrency/syncmeth.html 来自Java Tutorials站点http://download.oracle.com/javase/tutorial/essential/concurrency/syncmeth.html

  1. 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. 当一个线程正在为对象执行同步方法时,所有其他线程调用同一对象的同步方法(暂停执行)直到第一个线程完成对象。

  2. when a synchronized method exits, it automatically establishes a happens-before relationship with any subsequent invocation of a synchronized method for the same object. 当synchronized方法退出时,它会自动与同一对象的同步方法的任何后续调用建立一个before-before关系。 This guarantees that changes to the state of the object are visible to all threads 这可以保证对所有线程都可以看到对象状态的更改

So Java will ensure that if 2 threads are executing the same method, the methods will not executed consurrently but one after another. 所以Java将确保如果2个线程正在执行相同的方法,那么这些方法将不会一个接一个地执行。

But you need to be aware of the Liveness problem, http://download.oracle.com/javase/tutorial/essential/concurrency/starvelive.html 但是你需要了解Liveness问题, http://download.oracle.com/javase/tutorial/essential/concurrency/starvelive.html

And also whether you are locking uncessarily, cause in the code you used this , which locks the whole object, if your object only needs sync access to one variable you should just lock that variable. 而且你是否在不经意地锁定,导致你使用的代码,它锁定整个对象,如果你的对象只需要同步访问一个变量,你应该锁定该变量。

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

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