Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/381.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 即使在所有线程完成后,应用程序也会挂起几分钟_Java_Multithreading_Concurrency_Executorservice - Fatal编程技术网

Java 即使在所有线程完成后,应用程序也会挂起几分钟

Java 即使在所有线程完成后,应用程序也会挂起几分钟,java,multithreading,concurrency,executorservice,Java,Multithreading,Concurrency,Executorservice,我使用毒药丸终止模式将一个工作生产者/消费者示例从Thread/Runnable转换为Executor/Callable/BlockingQueues 如果运行下面的程序,即使每个线程都已完成,它也会挂起几分钟。 jstack显示了一个队列上阻塞的大量线程,这些线程似乎与应用程序无关 "pool-1-thread-10" prio=5 tid=10b08d000 nid=0x10d91c000 waiting on condition [10d91b000] java.lang.Threa

我使用毒药丸终止模式将一个工作生产者/消费者示例从Thread/Runnable转换为Executor/Callable/BlockingQueues

如果运行下面的程序,即使每个线程都已完成,它也会挂起几分钟。 jstack显示了一个队列上阻塞的大量线程,这些线程似乎与应用程序无关

"pool-1-thread-10" prio=5 tid=10b08d000 nid=0x10d91c000 waiting on condition [10d91b000]
   java.lang.Thread.State: TIMED_WAITING (parking)
    at sun.misc.Unsafe.park(Native Method)
    - parking to wait for  <7f3113510> (a java.util.concurrent.SynchronousQueue$TransferStack)
    at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:198)
    at java.util.concurrent.SynchronousQueue$TransferStack.awaitFulfill(SynchronousQueue.java:424)
    at java.util.concurrent.SynchronousQueue$TransferStack.transfer(SynchronousQueue.java:323)
    at java.util.concurrent.SynchronousQueue.poll(SynchronousQueue.java:874)
    at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:945)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:907)
    at java.lang.Thread.run(Thread.java:680)
“pool-1-thread-10”优先级=5 tid=10b08d000 nid=0x10d91c000等待状态[10d91b000]
java.lang.Thread.State:定时等待(停车)
在sun.misc.Unsafe.park(本机方法)
-停车等待(java.util.concurrent.SynchronousQueue$TransferStack)
位于java.util.concurrent.locks.LockSupport.parknos(LockSupport.java:198)
位于java.util.concurrent.SynchronousQueue$TransferStack.WaitFulfill(SynchronousQueue.java:424)
位于java.util.concurrent.SynchronousQueue$TransferStack.transfer(SynchronousQueue.java:323)
位于java.util.concurrent.SynchronousQueue.poll(SynchronousQueue.java:874)
位于java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:945)
位于java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:907)
运行(Thread.java:680)
我不明白为什么应用程序挂起。感谢您的帮助。 多谢各位

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Random;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.LinkedBlockingQueue;

public class ProducersConsumers {
    private LinkedBlockingQueue<Item> queue = new LinkedBlockingQueue<Item>();
    private static final ExecutorService executorPool = Executors.newCachedThreadPool();
    private Random randGenerator = new Random(System.currentTimeMillis());

    private class Item {
        private boolean done = false;
        private String message;

        private Item(boolean done) {
            this.done = done;
        }

        private Item(String message) {
            this.message = message;
        }

        public boolean isDone() {
            return done;
        }

        public String getMessage() {
            return message;
        }
    }

    private class Producer implements Callable<Long> {
        private final int id;
        private Integer numOfMessages;

        private Producer(int id, int numOfMessages) {
            this.id = id;
            this.numOfMessages = numOfMessages;
        }

        @Override
        public Long call() throws Exception {
            long totalTime = 0;
            while (numOfMessages > 0) {
                String message;
                synchronized (numOfMessages) {
                    long starttime = System.nanoTime();
                    int msgLength = randGenerator.nextInt(20000);
                    StringBuilder sb = new StringBuilder(msgLength);
                    for (int a = 0; a < msgLength; a++) {
                        sb.append((char) ('a' + randGenerator.nextInt(26)));
                    }
                    message = sb.toString();
                    long endtime = System.nanoTime();
                    totalTime += endtime - starttime;
                }
                numOfMessages--;
                queue.put(new Item(message));
            }
            System.out.println("-------------Producer " + id + " is done.");
            queue.put(new Item(true));
            return totalTime;
        }
    }

    private class Consumer implements Callable<Long> {
        private String monitor = "monitor";
        private final int id;

        private Consumer(int id) {
            this.id = id;
        }

        @Override
        public Long call() throws Exception {
            long totalTime = 0;
            while (true) {
                Item item = queue.take();
                if (item.isDone()) {
                    break;
                }
                synchronized (monitor) {
                    long starttime = System.nanoTime();
                    StringBuilder sb = new StringBuilder(item.getMessage());
                    sb = sb.reverse();
                    String message = sb.toString();
                    long endtime = System.nanoTime();
                    totalTime += endtime - starttime;
                }
            }
            System.out.println("+++++++++++++Consumer " + id + " is done.");
            return totalTime;
        }
    }

    public void begin(int threadCount) throws InterruptedException, ExecutionException {
        Collection<Producer> producers = new ArrayList<Producer>();
        for (int i = 0; i < threadCount; i++) {
            producers.add(new Producer(i, randGenerator.nextInt(5)));
        }
        Collection<Consumer> consumers = new ArrayList<Consumer>();
        for (int i = 0; i < threadCount; i++) {
            consumers.add(new Consumer(i));
        }
        try {
            long starttime = System.nanoTime();
            List<Future<Long>> producerFutureList = executorPool.invokeAll(producers);
            List<Future<Long>> consumerFutureList = executorPool.invokeAll(consumers);
            long producerTotalTime = 0;
            long consumerTotalTime = 0;

            for (Future<Long> future : producerFutureList) {
                producerTotalTime += future.get();
            }
            for (Future<Long> future : consumerFutureList) {
                consumerTotalTime += future.get();
            }
            long mainThreadTotalTime = System.nanoTime() - starttime;

            System.out.println("producerTotalTime   " + producerTotalTime);
            System.out.println("consumerTotalTime   " + consumerTotalTime);
            System.out.println("mainThreadTotalTime " + mainThreadTotalTime);
            System.out.println("Difference          " + (producerTotalTime + consumerTotalTime - mainThreadTotalTime));
        } catch (InterruptedException e) {
            e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
            throw e;
        } catch (ExecutionException e) {
            e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
            throw e;
        }

    }

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        ProducersConsumers prodcon = new ProducersConsumers();
        prodcon.begin(20);
    }
}
import java.util.ArrayList;
导入java.util.Collection;
导入java.util.List;
导入java.util.Random;
导入java.util.concurrent.Callable;
导入java.util.concurrent.ExecutionException;
导入java.util.concurrent.ExecutorService;
导入java.util.concurrent.Executors;
导入java.util.concurrent.Future;
导入java.util.concurrent.LinkedBlockingQueue;
公共类生产者消费者{
私有LinkedBlockingQueue=新LinkedBlockingQueue();
私有静态最终ExecutorService executorPool=Executors.newCachedThreadPool();
private Random randGenerator=新随机(System.currentTimeMillis());
私人类项目{
私有布尔完成=假;
私有字符串消息;
私有项(布尔完成){
this.done=done;
}
私有项(字符串消息){
this.message=消息;
}
公共布尔isDone(){
已完成的返回;
}
公共字符串getMessage(){
返回消息;
}
}
私有类生产者实现了可调用{
私有最终int id;
私有整数消息;
私有生产者(int-id,int-numOfMessages){
this.id=id;
this.numOfMessages=numOfMessages;
}
@凌驾
public Long call()引发异常{
长总时间=0;
while(numOfMessages>0){
字符串消息;
已同步(NUMOF消息){
long starttime=System.nanoTime();
int msgLength=randGenerator.nextInt(20000);
StringBuilder sb=新StringBuilder(msgLength);
对于(int a=0;awhile (numOfMessages > 0) {
    // blah
    synchronized (numOfMessages) {
        // blah
    }
}