java生产者消费者问题 - 使线程等到其他人完成之前完成

时间:2014-08-15 21:58:19

标签: java multithreading time synchronization producer-consumer

我目前正在处理多线程的生产者消费者问题。首先有1000个字节可用,使用RAM nad驱动程序已经占用了500个,让我使用500个线程。将有4个生产者,如下:

  1. 启动BubbleWitch2会话10秒的线程,每个需要100个字节的RAM 第二
  2. 启动Spotify流20秒的线程,每秒需要250个字节的RAM。
  3. 系统和管理线程,它们一起每秒需要50个字节的RAM,以及 一旦被调用,就执行一段随机的时间。
  4. 用于安装2 KB的新安全更新的线程,该安全更新将存储到磁盘,并且在安装时每秒需要150个字节的RAM。假设系统中有足够的磁盘容量来支持该线程。
  5. 该程序旨在在安全更新完成后停止执行。理想情况下,这应该在不设置线程优先级的情况下实现。它工作得比较早,但现在当我运行程序时,安全线程正在中间完成,而spotify正在完成笑声。是否有任何错误可能导致这种情况?我在下面提供了我的代码。我还没有将所有字节大小分配给线程和缓冲区。

    我的主要方法。

    /**
     * Created by User on 10/08/2014.
     */
    public class ProducerConsumerTest {
            public static void main(String[] args) throws InterruptedException {
                Buffer c = new Buffer();
                BubbleWitch2 p1 = new BubbleWitch2(c, 1);
                Processor c1 = new Processor(c, 2);
                Spotify p2 = new Spotify(c, 3);
                SystemManagement p3 = new SystemManagement(c,4);
                securityUpdate p4 = new securityUpdate(c,5, p1,p2,p3);
    
                p1.setName("BubbleWitch2 ");
                p2.setName("Spotify ");
                p3.setName("System Management ");
                p4.setName("Security Update ");
    
                c1.start();
                p1.start();
                p2.start();
                p3.start();
                p4.start();
    
                p2.join();
                p3.join();
                p4.join();
                System.exit(0);
    
            }
        }
    

    我的缓冲区/小班级

    /**
     * Created by User on 10/08/2014.
     */
    class Buffer {
        private int contents;
        private boolean available = false;
        public synchronized int get() {
            while (available == false) {
                try {
                    wait();
                }
                catch (InterruptedException e) {
                }
            }
            available = false;
            notifyAll();
            return contents;
        }
        public synchronized void put(int value) {
            while (available == true) {
                try {
                    wait();
                }
                catch (InterruptedException e) {
                }
            }
            contents = value;
            available = true;
            notifyAll();
        }
    }
    

    我的消费者类

    class Processor extends Thread {
        private Buffer cubbyhole;
        private int number;
        public Processor(Buffer c, int number) {
            cubbyhole = c;
            this.number = number;
        }
        public void run() {
            int value = 0;
            for (int i = 0; i < 60; i++) {
                value = cubbyhole.get();
                System.out.println("Processor #"
                        + this.number
                        + " got: " + value);
            }
        }
    }
    

    我的spotify生产者类

    class Spotify extends Thread {
        private Buffer buffer;
        private int number;
        private int bytes;
    
        public Spotify(Buffer c, int number) {
            buffer = c;
            this.number = number;
        }
    
        public void run() {
            for (int i = 0; i < 20; i++) {
                buffer.put(i);
                System.out.println(getName() + this.number
                        + " put: " + i);
                try {
                    sleep(1000);
                } catch (InterruptedException e) { }
            }
            System.out.println("*****************************");
            System.out.println("Spotify has finished executing.");
            System.out.println("*****************************");
    
        }
    }
    

    我的bubblewitch制作类

    import java.lang.*;
    import java.lang.System;
    /**
     * Created by User on 10/08/2014.
     */
    class BubbleWitch2 extends Thread {
        private Buffer buffer;
        private int number;
        private int bytes;
    
        public BubbleWitch2(Buffer c, int number) {
            buffer = c;
            this.number = number;
        }
    
        public void run() {
            for (int i = 0; i < 10; i++) {
                buffer.put(i);
                System.out.println(getName() + this.number
                        + " put: " + i);
                try {
                    sleep(1000);
                } catch (InterruptedException e) { }
            }
            System.out.println("*****************************");
            System.out.println("BubbleWitch2 has finished executing.");
            System.out.println("*****************************");
        }
    }
    

    我的系统管理生产者类

      class SystemManagement extends Thread {
            private Buffer buffer;
            private int number, min = 1, max = 15;
            private int loopCount = (int) (Math.random() * ( max - min ));
    
            public SystemManagement(Buffer c, int number) {
                buffer = c;
                this.number = number;
            }
    
            public void run() {
                for (int i = 0; i < loopCount; i++) {
                    buffer.put(i);
                    System.out.println(getName() + this.number
                            + " put: " + i);
                    try {
                        sleep(1000);
                    } catch (InterruptedException e) { }
                }
                System.out.println("*****************************");
                System.out.println("System Management has finished executing.");
                System.out.println("*****************************");
            }
        }
    

    我的安全更新类

    /**
     * Created by User on 14/08/2014.
     */
    import java.lang.*;
    import java.lang.System;
    
    /**
     * Created by User on 11/08/2014.
     */
    class securityUpdate extends Thread {
        private Buffer buffer;
        private int number;
        private int bytes = 150;
        private int process = 0;
    
        public securityUpdate (Buffer c, int number, BubbleWitch2 bubbleWitch2, Spotify spotify, SystemManagement systemManagement) throws InterruptedException {
            buffer = c;
            this.number = number;
            bubbleWitch2.join();
            spotify.join();
            systemManagement.join();
        }
    
        public void run() {
    
            for (int i = 0; i < 10; i++) {
                buffer.put(i);
                System.out.println(getName() + this.number
                        + " put: " + i);
                try {
                    sleep(1000);
                } catch (InterruptedException e) { }
            }
            System.out.println("*****************************");
            System.out.println("Security Update has finished executing.");
            System.out.println("*****************************");
        }
    }
    

    我希望能够让它在最后运行而不需要在计数中硬编码不同的数字,因为我将需要在代码中计算以每秒150字节的速度运行2000字节的大小所需的时间,这将是使硬编码无关紧要。有没有人有任何想法?

2 个答案:

答案 0 :(得分:2)

我不确定我是否完全理解这个问题,但你正在securityUpdate的构造函数中加入线程:

bubbleWitch2.join();
spotify.join();
systemManagement.join();

这些连接发生在线程启动之前,所以它们都是无操作。

同样,我在这里没有完全理解这个问题,但似乎你正试图让securityUpdate等待这三个线程完成。如果是这样,您可能希望将这些调用移至join()方法run()

或类似的东西。祝你好运。

答案 1 :(得分:2)

使用更简单的执行器框架尝试以下修改后的代码: -

public class ProducerConsumerTest {
    public static void main(String[] args) throws InterruptedException {
        BlockingQueue<Integer> c = new ArrayBlockingQueue<Integer>(1);
        CountDownLatch doneSignal = new CountDownLatch(3);

        Processor c1 = new Processor(c, 2, doneSignal);

        BubbleWitch2 p1 = new BubbleWitch2(c, 1, doneSignal);        
        Spotify p2 = new Spotify(c, 3, doneSignal);
        SystemManagement p3 = new SystemManagement(c,4, doneSignal);
        SecurityUpdate p4 = new SecurityUpdate(c,5, doneSignal);

        p1.setName("BubbleWitch2 ");
        p2.setName("Spotify ");
        p3.setName("System Management ");
        p4.setName("Security Update ");

        ExecutorService exec = Executors.newCachedThreadPool();
        exec.submit(c1);
        exec.submit(p1);
        exec.submit(p2);
        exec.submit(p3);        

        Future<?> securityFuture = exec.submit(p4);

        try {
            while(securityFuture.get()!=null) {

            }           
            exec.shutdown();
            while(exec.awaitTermination(1000, TimeUnit.MILLISECONDS)) {

            }
            exec.shutdownNow();
        } catch (ExecutionException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        System.exit(0);
    }
}
class Processor extends Thread {
    private BlockingQueue<Integer> cubbyhole;
    private int number;
    private CountDownLatch doneSignal;

    public Processor(BlockingQueue<Integer> c, int number,CountDownLatch doneSignal) {
        cubbyhole = c;
        this.number = number;
        this.doneSignal = doneSignal;
    }
    public void run() {
        int value = 0;
       // for (int i = 0; i < 60; i++) {
        while(true) {
            try {
                value = cubbyhole.take();
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                //e.printStackTrace();
            }
            System.out.println("Processor #"
                    + this.number
                    + " got: " + value);
        }
        //doneSignal.countDown();
    }
}

class Spotify extends Thread {
    private BlockingQueue<Integer> buffer;
    private int number;
    private int bytes;
    private CountDownLatch doneSignal;

    public Spotify(BlockingQueue<Integer> c, int number, CountDownLatch doneSignal) {
        buffer = c;
        this.number = number;
        this.doneSignal = doneSignal;
    }

    public void run() {
        for (int i = 0; i < 20; i++) {
            try {
                buffer.put(i);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            System.out.println(getName() + this.number
                    + " put: " + i);           
        }
        System.out.println("*****************************");
        System.out.println("Spotify has finished executing.");
        System.out.println("*****************************");
        doneSignal.countDown();
    }
}

class BubbleWitch2 extends Thread {
    private BlockingQueue<Integer> buffer;
    private int number;
    private int bytes;
    private CountDownLatch doneSignal;

    public BubbleWitch2(BlockingQueue<Integer> c, int number, CountDownLatch doneSignal) {
        buffer = c;
        this.number = number;
        this.doneSignal = doneSignal;
    }

    public void run() {
        for (int i = 0; i < 10; i++) {
            try {
                buffer.put(i);
            } catch (InterruptedException e1) {
                // TODO Auto-generated catch block
                e1.printStackTrace();
            }
            System.out.println(getName() + this.number
                    + " put: " + i);

        }
        System.out.println("*****************************");
        System.out.println("BubbleWitch2 has finished executing.");
        System.out.println("*****************************");
        doneSignal.countDown();
    }
}

class SystemManagement extends Thread {
    private BlockingQueue<Integer> buffer;
    private int number, min = 1, max = 15;
    private int loopCount = (int) (Math.random() * ( max - min ));
    private CountDownLatch doneSignal;

    public SystemManagement(BlockingQueue<Integer> c, int number, CountDownLatch doneSignal) {
        buffer = c;
        this.number = number;
        this.doneSignal = doneSignal;
    }

    public void run() {
        for (int i = 0; i < loopCount; i++) {
            try {
                buffer.put(i);
            } catch (InterruptedException e1) {
                // TODO Auto-generated catch block
                e1.printStackTrace();
            }
            System.out.println(getName() + this.number
                    + " put: " + i);

        }
        System.out.println("*****************************");
        System.out.println("System Management has finished executing.");
        System.out.println("*****************************");
        doneSignal.countDown();
    }
}

class SecurityUpdate extends Thread {
    private BlockingQueue<Integer> buffer;
    private int number;
    private int bytes = 150;
    private int process = 0;
    private CountDownLatch doneSignal;

    public SecurityUpdate (BlockingQueue<Integer> c, int number, CountDownLatch doneSignal) {
        buffer = c;
        this.number = number;
        this.doneSignal = doneSignal;
    }

    public void run() {
        try {
            doneSignal.await();         
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        for (int i = 0; i < 10; i++) {
            try {
                buffer.put(i);
            } catch (InterruptedException e1) {
                // TODO Auto-generated catch block
                e1.printStackTrace();
            }
            System.out.println(getName() + this.number
                    + " put: " + i);

        }
        System.out.println("*****************************");
        System.out.println("Security Update has finished executing.");
        System.out.println("*****************************");
    }
}

如果您有任何问题,请告诉我