当线程访问锁定的对象时,有没有办法运行一段代码?
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");
...
}
答案 0 :(得分:1)
对于受synchronized
保护的对象监视器,否则它会成功锁定或无限期地阻塞等待锁定。
如果您使用的是ReentrantLock
等,则可以选择更多选项:
lock
来无限期地等待,就像对象监视器一样。tryLock
来等待有限的时间。tryLock
来立即返回。答案 1 :(得分:1)
优雅的解决方法可能如下所示:
// 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
来避免竞争条件。
也许另一种方法是使用监控线程定期轮询每个线程并宣布它被阻止。