繁体   English   中英

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

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

如果synchronized方法调用另一个synchronized方法,它是否是线程安全的?

void synchronized method1() {
     method2()
}

void synchronized method2() {
}

是的,当您将方法标记为已synchronized ,您实际上是这样做的:

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

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

当线程调用进入从方法1方法2,那么它会确保它持有锁到this ,它已经将,然后它可以通过。

当线程直接进入method1或method2时,它将阻塞直到它可以获得锁( this ),然后它将进入。

正如James Black在评论中所指出的那样,你必须要了解你在方法体内所做的事情。

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

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

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

突然,因为你正在寻找一个它不是线程安全的ConcurrentModificationException在你的未来,因为method3是不同步的,因此可以通过线程A,而线程B在工作被称为method1

是一个标有同步调用方法的另一个同步方法线程安全。

一般来说,不可能说。 这取决于方法的作用,以及相同和其他类的其他方法。

但是,我们可以确保不同线程对同一对象的method1和method2的调用不会同时执行。 根据方法的作用,这可能足以说该类对于这些方法是线程安全的。

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

  1. 对同一对象的两个同步方法的调用不可能进行交错。 当一个线程正在为对象执行同步方法时,所有其他线程调用同一对象的同步方法(暂停执行)直到第一个线程完成对象。

  2. 当synchronized方法退出时,它会自动与同一对象的同步方法的任何后续调用建立一个before-before关系。 这可以保证对所有线程都可以看到对象状态的更改

所以Java将确保如果2个线程正在执行相同的方法,那么这些方法将不会一个接一个地执行。

但是你需要了解Liveness问题, http://download.oracle.com/javase/tutorial/essential/concurrency/starvelive.html

而且你是否在不经意地锁定,导致你使用的代码,它锁定整个对象,如果你的对象只需要同步访问一个变量,你应该锁定该变量。

暂无
暂无

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

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