我正在同步和阻止同一对象。每个线程调用PuppetShow类中的testQueue()方法,该方法为要阻塞的每个线程实例化一个不同的对象。我的问题是,一旦capacity == 0,遇到该条件的第一个线程将在其对象上调用wait(),然后程序挂起,并且没有其他线程在运行。第三个线程根据println语句输出“ waaah”,然后不执行其他任何行,尽管我在此之后实例化了线程。
如何在PuppetShow()类的testQueue方法中移过lock.wait()行?
我希望能够阻塞不同的对象并将它们添加到向量中,以便将线程组排队。这就是为什么我要阻塞不同的对象,然后将它们添加到向量中的原因。要通知线程,我只需通知向量中某个位置的元素。
import java.util.Vector;
public class PuppetShow {
private int numSeats = 2;
private int capacity = numSeats;
private Vector<Object> attendingPuppetShow = new Vector<Object>();
public Vector<Object> waitingStudents = new Vector<Object>();
public void testQueue() {
Object lock = new Object();
System.out.println("testQueue begin");
synchronized(lock) {
if(testAttending(lock)) {
try {
System.out.println("waaah");
lock.wait();
System.out.println("ugh");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
public synchronized boolean testAttending(Object lock) {
System.out.println("testAttending");
boolean status;
if(capacity==0) {
waitingStudents.add(lock);
System.out.println("capacity="+capacity+" ws size="+waitingStudents.size());
status = true;
}
else {
capacity--;
attendingPuppetShow.add(lock);
System.out.println("capacity="+capacity+" aPS size="+attendingPuppetShow.size());
status = false;
}
return status;
}
public synchronized void testRelease() {
if(waitingStudents.size() > 0) {
while(waitingStudents.size() > 0) {
synchronized(waitingStudents.elementAt(0)) {
waitingStudents.elementAt(0).notify();
}
waitingStudents.removeElementAt(0);
capacity++;
}
}
}
}
class GreenStudent extends Thread {
private PuppetShow ps = new PuppetShow();
public GreenStudent(int id, PuppetShow ps) {
setName("GreenStudent-" + id);
this.ps = ps;
}
@Override
public void run() {
System.out.println(getName()+" queuing for show");
ps.testQueue();
}
}
class StaffMember extends Thread {
private PuppetShow ps = new PuppetShow();
public StaffMember(int id, PuppetShow ps) {
setName("StaffMember-" + id);
this.ps = ps;
}
@Override
public void run() {
ps.testRelease();
}
}
class Driver {
public static void main(String[] args) {
// TODO Auto-generated method stub
PuppetShow ps = new PuppetShow();
GreenStudent gs1 = new GreenStudent(1, ps);
GreenStudent gs2 = new GreenStudent(2, ps);
GreenStudent gs3 = new GreenStudent(3, ps);
StaffMember sm = new StaffMember(1,ps);
gs1.run();
gs2.run();
gs3.run();
sm.run();
}
}
答案 0 :(得分:1)
gs1.run();
gs2.run();
gs3.run();
sm.run();
需要成为
gs1.start();
gs2.start();
gs3.start();
sm.start();
在您的示例中,run
将由调用线程(主线程)调用。 start
将启动另一个线程,然后最终调用run
。