簡體   English   中英

當線程被內部鎖阻止時執行代碼

[英]Executing a code when thread gets Blocked by Intrinsic Lock

當線程訪問鎖定的對象時,有什么方法可以運行一段代碼?

public class Student implements Runnable {

private String name;
private Workshop w;

public Student(String name,Workshop workshop) {
    this.name = name;
    this.w=workshop;
}

@Override
public void run() {

    this.w.getReady();
    this.w.file(this.name);
    this.w.cut(this.name);
    this.w.punch(this.name); //Synchronized Method

    if(Thread.currentThread().getState()==Thread.State.BLOCKED)
        System.out.println(this.name+" is waiting in queue");

    System.out.println(this.name+" has finished and is going home");
}

}

這是對Workshop場景的模擬,其中每個學生都必須銼削,切割和打孔金屬工件。
由於打孔是依次進行的,因此我已宣布它為同步的,因為每個學生(線程)都必須等待輪到打孔。
我想知道的是,是否有一些內置方法或編寫一種方法的方法,該方法在線程被阻塞並等待內部鎖被解鎖時執行。


public void onBlock() {
    System.out.println(this.name+" is waiting in queue");
    ...
}

用於通過保護對象顯示器synchronized ,不,它要么成功鎖定或阻塞無限期地等待鎖。

如果您使用的是ReentrantLock或類似工具,則有更多選擇:

  1. 您可以像調用對象監視器那樣無限期地等待,方法是調用lock
  2. 您可以通過使用超時值調用tryLock來等待有限的時間。
  3. 如果沒有參數,可以通過調用tryLock立即返回如果鎖不可用。

優雅的解決方法可能如下所示:

// In the Workshop class.
private static final AtomicReference<Boolean> IN_USE = new AtomicReference<>(false);

private void getInLineToPunch(String name) {
  while(!IN_USE.compareAndSet(false, true)) {
    System.out.println(name + " is waiting in line to punch.");
    try {
      Thread.sleep(SOME_INTERVAL);
    } catch(InterruptedException ex) {
      // This will probably not occur unless you interrupt this thread on purpose.
      ex.printStackTrace();
    }
  }

  // At this point, no one is using the punch.
  System.out.println(name + " will now use the punch.");
  punch();

  // I am done with the punch.
  System.out.println(name + " is done with the punch.");
  IN_USE.set(false);
}

對於這種方法,必須使用AtomicReference以避免競爭條件。

也許另一種方法是使用監視線程來定期輪詢每個線程並宣布其已被阻塞。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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