[英]Executing two synchronized method by two thread in java
可以說我在類ABC
有synchronized hi(){}
和synchronized hello(){}
方法的方法。 兩個線程t1
和t2
分別執行t1.hi()
和t2.hello()
。 它們可以同時執行還是存在任何問題?
否,同一對象中的2個同步方法不能同時執行:
https://docs.oracle.com/javase/tutorial/essential/concurrency/syncmeth.html
從文檔:
在同一個對象上兩次同步方法調用是不可能交織的。 當一個線程正在執行對象的同步方法時,所有其他調用同一對象塊的同步方法的線程(掛起執行),直到第一個線程對該對象完成。
這里的關鍵是鎖定在對象上。 正如Thomas所指出的,大概t1
和t2
是同一類的不同實例,因此它們實際上可以同時執行hi()
和hello()
。
如果t1
和t2
僅是在同一對象上調用hi()
和hello()
2個不同線程,則上述語義成立,並且這2個方法不能並行執行。
在方法聲明中使用synced關鍵字使用隱式對象,對於靜態方法,它是類對象;對於非靜態方法,是實例對象本身。
范例1:
public class A {
public synchronized void setName() {
//
}
public synchronized void setAge() {
//
}
}
假設有兩個線程Thread-1和Thread-2。
現在線程1嘗試訪問setName()和線程2 setAge()
讓線程1輸入1st並按住密鑰,線程2將等待直到密鑰可用。 困惑?
因此,由於沒有顯式對象用於同步,因此使用相同的密鑰來同步兩個
“ A的對象,分別用於通過線程1和線程2訪問setName()方法和setAge()方法”。
A a = new A("Name", 1);
Runnable nameR = () -> a.getName();
Runnable ageR = () -> a.getAge();
Thread nameThread = new Thread(nameR);
Thread ageThread = new Thread(nameR);
nameThread.start();
ageThread.start();
但這是有問題的,因為即使具有密鑰的線程無法訪問它,也沒有其他線程能夠運行其他方法。
因此,要解決此問題,我們需要有單獨的鍵來獨立同步getName和getAge方法。
public class A {
private final Object nameLock = new Object();
private final Object ageLock = new Object();
public void setName() {
synchronized(nameLock) {
//
}
}
public synchronized void setAge() {
synchronized(ageLock) {
//
}
}
}
希望這可以幫助!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.