线程随机停止,没有错误

时间:2017-03-09 15:56:28

标签: java multithreading

所以我基本上都在学习线程,所以我不是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。对代码的质量表示抱歉,但我真的不知道是什么导致了这个问题,因为我是线程的新手,所以我无法缩小它。

提前致谢。 :)

1 个答案:

答案 0 :(得分:2)

您的问题是您没有唤醒正在SingleBufferMonitor对象中的隐式监视器上等待的所有线程。使用监视器涉及3种方法:等待,通知和 notifyAll 。 notifyAll()将唤醒在监视器上等待的所有当前线程。您调用的方法只会唤醒一个线程。由于您一次只唤醒一个线程,因此一个生产者调用put()可以唤醒另一个生产者,这会将缓冲区视为已满,并再次调用wait()。两位消费者仍在等待,现在两位制作人都在等待,而且该计划将不再进一步发展。如果您更改为使用notifyAll(),您将看到程序完成。