我有以下场景…有两个DJ正在尝试播放音乐,但他们显然只能播放CD,如果另一个DJ在那一刻没有播放相同的CD,所以我有这些类,我试图使用同步为另一个线程锁定CD
public class cd {
private boolean played = false;
public void play() {
this.played = true;
Thread.sleep(2000);
}
//other methods, e.g. skip a song or put the CD back in the collection
public boolean isAvailable() {
return !(this.played);
}
}
public class turntable {
private boolean used = false;
public void use() {
this.played = true;
Thread.sleep(2000);
}
public boolean isFree() {
return !(this.used);
}
...
}
DJ类:public class DJ implements Runnable {
CD disk;
Turntable tt;
//constructor
public void run() {
//do something else, e.g. go to the bar
tt.use();
disk.play();
disk.skipSong();
disk.putBack();
tt.leave();
//do something else, e.g. smoke a cigarette
}
}
现在我试图阻止DJ_2的当前CD,而DJ_1在这部分:
应该阻塞CD的部分:
tt.use();
disk.play();
disk.skipSong();
disk.putBack();
tt.leave();
但是如果DJ_1把CD放回去了,但是现在正在抽烟,CD显然应该是可用的。
所以我的问题是……我怎么能阻止一个线程的运行方法的一部分,并设置它相对于不同线程的同一部分(请记住我试图解决同步的问题)对于CD类中的play方法
public synchronized void play() {
while(this.played) {
try {
wait();
} catch (InterruptedException e) {}
}
this.played = true;
// suppose each DJ can play the disk for 2 seconds and then has to yield the fun to others
Thread.sleep(2000);
this.played = false;
notifyAll();
}
那么每个线程应该有相同的CD实例
public static void main(String){
CD cd = new CD();
DJ dj1 = new DJ();
dj1.disk = cd;
Thread threadDJ1 = new Thread(dj1);
DJ dj2 = new DJ();
dj2.disk = cd;
Thread threadDJ2 = new Thread(dj2);
threadDJ1.start();
threadDJ2.start();
}
Java文档中有关于这类主题的很好的例子
synchronized
可以在对象上,而不仅仅是一个方法。在应该阻塞的部分使用
synchronized (tt) {
tt.use();
synchronized (disk) {
disk.play();
disk.skipSong();
disk.putBack();
}
tt.leave();
}
在唱盘和磁盘上的所有sync
都要按相同的顺序同步,否则会死锁,&音乐停止了