0
我有3個類,如下所示。我已經使用synchronized(b)
這樣,一個對象獲取B對象上的鎖,並且在A
中的foo
方法完成工作之前,將不會調用b中的任何方法。Java多線程同步(對象)
但是,這似乎不起作用(見最後的輸出)。事實上,racethread
能夠調用對象b上的方法。
注意:您可以創建一個簡單的java項目,並將下面的代碼添加到一個文件中以嘗試並執行。
package com.threads.main.deadlock;
class A {
void foo(B b) {
synchronized (b) { // Trying to get lock on b here
String name = Thread.currentThread().getName();
System.out.println(name + " entered A.foo");
try {
Thread.sleep(1000);
} catch (Exception e) {
System.out.println("A Interrupted");
}
System.out.println(name + " trying to call B.last()");
b.last();
}
}
synchronized void last() {
System.out.println("Inside A.last");
}
}
class B {
void bar(A a) {
synchronized (a) {
String name = Thread.currentThread().getName();
System.out.println(name + " entered B.bar");
try {
Thread.sleep(1000);
} catch (Exception e) {
System.out.println("B Interrupted");
}
System.out.println(name + " trying to call A.last()");
a.last();
}
}
synchronized void last() {
System.out.println("Inside B.last");
}
}
public class Deadlock implements Runnable {
A a = new A();
B b = new B();
Deadlock() {
Thread.currentThread().setName("MainThread");
Thread t = new Thread(this, "RacingThread");
t.start();
new Thread(new Dum(a)).start();
a.foo(b); // get lock on a in this thread.
System.out.println("Back in main thread");
}
public void run() {
b.bar(a); // get lock on b in other thread.
System.out.println("Back in other thread");
}
public static void main(String args[]) {
new Deadlock();
}
}
class Dum implements Runnable {
A a = null;
public Dum(A a) {
this.a = a;
}
@Override
public void run() {
int i =0;
while (i++ < 5) {
System.out.println("Trying a.last .. dum");
a.last();
}
}
}
輸出:
RacingThread entered B.bar
Trying a.last .. dum
MainThread entered A.foo
RacingThread trying to call A.last()
MainThread trying to call B.last()
Inside B.last
Inside A.last
Back in other thread
Back in main thread
Inside A.last
Trying a.last .. dum
Inside A.last
Trying a.last .. dum
Inside A.last
Trying a.last .. dum
Inside A.last
Trying a.last .. dum
Inside A.last
真的不清楚你在這裏期待什麼;沒有什麼會導致僵局。 –
可能是另一種誤解2線程需要在同一個對象監視器上進行同步的情況,並且沒有辦法「鎖定對象」。 – Kayaman
@Kayaman,你可否請求詳細說明'2個線程需要在同一個對象監視器上同步',你可以修改這個類並顯示它。很難理解,因爲我是多線程新手。另外,當我添加同步(對象)對象時,下一點將被剛剛進入對象監視器的線程鎖定;並且在線程釋放監視器之前,鎖定對象內的任何方法都不會被其他線程訪問? – Zeus