如果同步方法调用另一个同步方法,它是否线程安全?从另一个同步方法调用同步方法是否安全?
void synchronized method1() {
method2()
}
void synchronized method2() {
}
如果同步方法调用另一个同步方法,它是否线程安全?从另一个同步方法调用同步方法是否安全?
void synchronized method1() {
method2()
}
void synchronized method2() {
}
是的,当你方法标记为,那么你真的这样做:
void method1() {
synchronized (this) {
method2()
}
}
void method2() {
synchronized (this) {
}
}
当线程调用进入从方法1方法2,那么将确保其持有的锁this
,它已经,然后它可以通过。
当线程直接进入method1或method2时,它会阻塞,直到它可以获得锁(this
),然后它将进入。
正如詹姆斯布莱克在评论中指出的那样,你必须知道你在方法体内做了什么。
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
工作进行调用。
我试图回答一个几乎与此处提问相同的问题。这是2个可能的答案(其他2个说不会运行),这是正确的? C. \t该代码将运行,但有潜在的死锁情况 D. \t代码将运行良好,因为Java提供了可重入同步,使线程可以多次获取相同的锁-----我猜测它是D,但也许潜在的死锁情况依赖于方法体? – 2015-05-10 01:35:26
@ user3140993这里的代码没有死锁的机会。 'method3'显示不安全的线程操作,但是您关注的是重入同步。 – pickypg 2015-07-28 02:49:48
从Java教程网站http://download.oracle.com/javase/tutorial/essential/concurrency/syncmeth.html
这是不可能的同一对象的同步方法交错两个调用。当一个线程正在执行一个对象的同步方法时,所有其他线程调用同一对象的同步方法块(挂起执行),直到第一个线程完成对象。
当一个同步方法退出时,它会自动与同一对象的任何后续调用同步方法建立一个前后关系。这保证了更改对象的状态是可见的所有线程
所以Java将确保如果两个线程都在执行同样的方法,该方法不会consurrently但接二连三执行。
但是你需要知道的活跃度的问题,http://download.oracle.com/javase/tutorial/essential/concurrency/starvelive.html
而且也不管你是锁定uncessarily,原因在您使用这个,它锁定了整个对象的代码,如果你的对象只需要同步访问一个变量,你应该只锁定该变量。
@Stephen Lee - 你不能锁定一个变量。然后你说'synchronized(this.someVar)'你正在查看引用保存在'someVar'中的对象。区别非常重要。 – 2011-04-27 02:43:41
是一种用synchronized调用另一个同步方法线程安全的方法。
一般来说,这是不可能说的。它取决于方法的作用,以及同一类和其他类中的其他方法。
但是,我们可以确定,由不同线程创建的同一个对象上的method1和method2调用不会同时执行。根据这些方法的作用,这个可能是就足以说这个类对于这些方法是线程安全的。
这篇文章有帮助吗,或者你困惑在哪里? http://kalyanchakravarthy.net/?p=413 – 2011-04-27 02:23:18
是的 - 您实际上并不需要将method2标记为synchronized,假定它只在上面给出的上下文中调用。 – debracey 2011-04-27 02:23:52
另外,它是否是线程安全的将取决于两种方法中发生的情况。例如,如果他们调用非线程安全列表,那么如果其他线程可以修改该集合,则它们可能不是线程安全的。 – 2011-04-27 02:24:20