所以我基本上都在学习线程,所以我不是100%肯定他们,但我创造了两个生产者和两个消费者,他们工作正常,但我已经改变了一些东西现在他们不是吗?
public class SingleBufferMonitor {
private int buffer;
private boolean full;
public SingleBufferMonitor(){
full = false;
}
public synchronized int get(){
while(full == false) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
notify();
full = false;
return buffer;
}//get
public synchronized void put(int value){
while(full == true){
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
buffer = value;
full = true;
notify();
}//put
}
}
public class ConsumerThread extends Thread {
private int aValue;
private SingleBufferMonitor sharedBuffer;
//private Random rand = new Random();
public ConsumerThread(SingleBufferMonitor buffer, String name){
super(name);
sharedBuffer = buffer;
}
public void run(){
String entrant;
for(int count=1; count < 10; count++){
try {
Thread.sleep(1000);
aValue = sharedBuffer.get();
} catch (InterruptedException e) {
e.printStackTrace();
}
if(count == 1){
entrant = "person";
}
else{
entrant = "people";
}
System.out.println(getName() + aValue + " " + entrant +" left");
}
}
}
}
public class ProducerThread extends Thread {
private SingleBufferMonitor sharedBuffer;
private Random rand = new Random();
public long startTime, endTime, timeTaken, averageTime;
public ProducerThread(SingleBufferMonitor buffer, String name){
super(name);
sharedBuffer = buffer;
}
public void run(){
int tSleep = rand.nextInt(1000);
String entrant;
int count;
for(count = 1; count < 10; count++){
try {
startTime = System.currentTimeMillis();
Thread.sleep(tSleep);
sharedBuffer.put(count);
endTime = System.currentTimeMillis();
timeTaken = endTime - startTime;
averageTime = averageTime + timeTaken;
} catch (InterruptedException e) {
e.printStackTrace();
}
if(count == 1){
entrant = "person";
}
else{
entrant = "people";
}
System.out.println(getName() + count + " " + entrant +" came in");
System.out.println("Time taken for " + count + " " + entrant + " to get into the nightclub: " + timeTaken);
}
System.out.println("Average Time taken for " + count + " people to get into the nightclub via entrance 1: " + averageTime);
}
}
}
class SingleBufferMonitorTest {
public static void main(String[] args) throws Exception{
SingleBufferMonitor box = new SingleBufferMonitor();
ProducerThread producer1 = new ProducerThread(box, "Entrance 1: ");
ProducerThread2 producer2 = new ProducerThread2(box, "Entrance 2: ");
ConsumerThread consumer = new ConsumerThread(box, "Exit 1: ");
ConsumerThread consumer2 = new ConsumerThread(box, "Exit 2: ");
producer1.start();
producer2.start();
consumer.start();
consumer2.start();
}
}
输出看起来像运行程序;
入场1:1人进来
一个人进入夜总会的时间:246
入口1:2人进来
2号出口:1人离开了
2人进入夜总会的时间:754
2号出口:2人离开
第二次看起来像;
入场2:1人进来
一个人进入夜总会的时间:552
入场1:1人进来
退出1:1人离开了
2号出口:1人离开了
一个人进入夜总会的时间:1000
入口2:2人进来
2人进入夜总会的时间:552
入口1:2人进来
2号出口:2人离开了
2人进入夜总会的时间:1001
2号出口:2人离开
etc.etc。
我只能看到它似乎是导致问题的消费者线程,因为它始终以&#34;退出&#34;结束。有时它也会在整个程序中完成,而不会停止并且工作正常。
猜测它与交织错误的线程有关,而且两者都要等待什么? (只是一个猜测)
P.S。对代码的质量表示抱歉,但我真的不知道是什么导致了这个问题,因为我是线程的新手,所以我无法缩小它。
提前致谢。 :)
答案 0 :(得分:2)
您的问题是您没有唤醒正在SingleBufferMonitor对象中的隐式监视器上等待的所有线程。使用监视器涉及3种方法:等待,通知和 notifyAll 。 notifyAll()将唤醒在监视器上等待的所有当前线程。您调用的方法只会唤醒一个线程。由于您一次只唤醒一个线程,因此一个生产者调用put()可以唤醒另一个生产者,这会将缓冲区视为已满,并再次调用wait()。两位消费者仍在等待,现在两位制作人都在等待,而且该计划将不再进一步发展。如果您更改为使用notifyAll(),您将看到程序完成。