簡體   English   中英

用Java中的兩個線程執行兩個同步方法

[英]Executing two synchronized method by two thread in java

可以說我在類ABCsynchronized hi(){}synchronized hello(){}方法的方法。 兩個線程t1t2分別執行t1.hi()t2.hello() 它們可以同時執行還是存在任何問題?

否,同一對象中的2個同步方法不能同時執行:

https://docs.oracle.com/javase/tutorial/essential/concurrency/syncmeth.html

從文檔:

在同一個對象上兩次同步方法調用是不可能交織的。 當一個線程正在執行對象的同步方法時,所有其他調用同一對象塊的同步方法的線程(掛起執行),直到第一個線程對該對象完成。

這里的關鍵是鎖定在對象上。 正如Thomas所指出的,大概t1t2是同一類的不同實例,因此它們實際上可以同時執行hi()hello()

如果t1t2僅是在同一對象上調用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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM