在for循环中创建许多不同的线程只生成一个线程(java)

时间:2018-01-11 23:26:43

标签: java multithreading

我试图在Java中使用Producer-Consumer模型中的许多线程,并且由于某种原因,它没有做它应该做的事情。

我有代码

List<Thread> consumers = new ArrayList<>();
            for (int i = 0; i < noOfThreads; i++) {

                Thread consumer = new Thread(new Runnable() {

                    String name = "Thread-" + UUID.randomUUID();
                    @Override
                    public void run() {
                        try {
                            pc.consume(name);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                });
                consumers.add(consumer);
                consumer.start();
                consumer.join();
            }

其中pc是ProducerConsumer,其使用方法是

 public void consume(String name) throws InterruptedException {
            while (true) {
                synchronized (this) {
                    while (subQueue.size() == 0) {
                        wait(2000);
                    }
                    Subscriber sub = subQueue.poll();

                     System.out.println(name);

                    uploadEndpointToPinpoint(sub);
                    notify();
                }
            }
        }

所以,当我运行它时,我希望看到它打印出10个不同的UUID,表明有10个线程正在运行 - 但是没有发生。相反,我得到:

Thread-c42ac697-d4ad-4944-a20e-907952f5d5ab
Thread-c42ac697-d4ad-4944-a20e-907952f5d5ab
Thread-c42ac697-d4ad-4944-a20e-907952f5d5ab
Thread-c42ac697-d4ad-4944-a20e-907952f5d5ab
Thread-c42ac697-d4ad-4944-a20e-907952f5d5ab
Thread-c42ac697-d4ad-4944-a20e-907952f5d5ab
Thread-c42ac697-d4ad-4944-a20e-907952f5d5ab

这意味着它只启动了其中一个线程。为什么for循环没有做我认为应该做的事情?

任何和所有帮助将不胜感激。

1 个答案:

答案 0 :(得分:1)

调用Thread#join()阻塞当前线程,直到目标线程不再运行。在你的循环中,你实际上是在启动一个线程,然后等待它完成,这就是你只看到一个线程的原因。如果要等待所有线程完成,则需要在创建线程的循环外部移动join()调用。

    List<Thread> consumers = new ArrayList<>();
    for (int i = 0; i < noOfThreads; i++) {

        Thread consumer = new Thread(new Runnable() {

            String name = "Thread-" + UUID.randomUUID();

            @Override
            public void run() {
                try {
                    pc.consume(name);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });
        consumers.add(consumer);
        consumer.start();
    }
    for (Thread thread : consumers) {
        thread.join();
    }