所有线程完成后,应用程序挂起几分钟(Application hangs for few minutes even after all the threads are done)
我将一个工作的生产者/消费者示例从Thread / Runnable转换为Executor / Callable / BlockingQueues并使用Poison Pill终止模式。
如果您运行下面的程序,即使每个线程都已完成,它也会挂起几分钟。 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)
我无法弄清楚应用程序挂起的原因。 任何帮助表示赞赏。 谢谢
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); } }
I converted a working Producer/Consumer Example from Thread/Runnable to Executor/Callable/BlockingQueues and using the Poison Pill termination pattern.
If you run the program below, it will hang for few minutes even though every thread has completed. jstack shows numerous threads blocked on a queue that is not seemingly related to the application.
"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)
I can not figure out why the application hangs. Any help is appreciated. Thank you
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); } }
原文:https://stackoverflow.com/questions/6767961
最满意答案
我建议使用现有的数据集,这里有一些来自这个acl wiki页面的例子:
语料库:
- ...
- 牛津文本档案意大利报纸语料库 ......
- ...
词汇网络
- EuroWordNet
- MultiWordNet - 一个多语言词汇数据库,意大利语WordNet与普林斯顿WordNet 1.6严格对齐......
请查看acl wiki页面上的完整列表,我认为你应该找到一个意大利语语料库,它可以让你定义意大利语单词。
I would suggest to use existing datasets, here are few examples from this acl wiki page:
Corpuses:
- ...
- Oxford Text Archive Corpus of Italian Newspapers ...
- ...
WordNets
- EuroWordNet
- MultiWordNet - a multilingual lexical database in which the Italian WordNet is strictly aligned with Princeton WordNet 1.6 ...
Please check the full list on the acl wiki page, I think you should find an italian corpus, which let you to define italian words.
相关问答
更多-
牵引力电脑学校怎么样[2019-01-17]
你好,选学校在网上片面了解是不全面的,参考性不高,个人角度和观念不同,发表的意见也不同,建议选择学校先选择专业,选一个自己喜欢的热门专业,有发展前途的专业,再选择开设这个专业的学校,这样有明确目标的学习才好 -
如何设置Nginx反向代理,我们公司现在要找个服务器做反向代理。可是我不知道怎么做。[2022-01-29]
没办法做这样的反向代理。 除非是 -> -> 如果是这样的话,配置是这样的 location /8080 { proxy_pass ; proxy_redirect off; } location /8000 { proxy_pass ; proxy_redirect off; } proxy的其它参数就自己设置了,可以参考下 -
如何设置Nginx反向代理,我们公司现在要找个服务器做反向代理。可是我不知道怎么做。[2022-08-01]
没办法做这样的 反向代理。 除非是 -> -> 如果是这样的话,配置是这样的 location /8080 { proxy_pass ; proxy_redirect off; } location /8000 { proxy_pass ; proxy_redirect off; } proxy的其它 参数就自己设置了,可以参考下 -
web服务器反向代理 怎么理解[2024-03-03]
简单说 我们内网访问facebook用的代理就叫正向代理 从美国访问我们内网需要的代理就叫反向代理 多台服务器处于一个内网,而我们要访问这些服务器,中间加一台 反向代理,根据各台服务器的负载,指定访问其中一台。这就叫负载均衡。 反向代理一般就是来干这个的 代理服务器来接受外部的连接请求,然后将请求转发给内部网络上的服务器,并将从服务器上得到的结果返回给外部的请求连接的客户端,此时代理服务器对外就表现为一个服务器。 反向代理一般作用: 1:减轻源服务器负载 2:保障源服务器 ... -
至于游戏机等,它们通常基于行业标准处理器。 游戏公司只购买处理器并使用它 - 他们不会花费2亿美元设计自己的CPU,并试图与摩托罗拉,英特尔,飞思卡尔等公司竞争。 这些相同的行业标准处理器通常具有工业标准调试端口,JTAG / BDM / NEXUS等。游戏机制造商也必须调试他们自己的设备! 那些经常用于反向设计控制台在运行其操作系统时正在做的事情。 这并不总是那么简单,因为您可能必须找到激活调试功能的方法,但这是一般性概述。 对于仿真器本身,您需要模拟硬件架构和硬件本身。 一旦你可以模拟这个,你可以简单地 ...
-
经过一些更多的研究和测试,我找到了解决方案。 显然根据标准[24.4.1 / 1],i.base()和i之间的关系是: &*(reverse_iterator(i)) == &*(i - 1) (来自Dr.Dobbs文章 ): 所以你需要在获取base()时应用偏移量。 所以解决办法是: m_CursorStack.erase( --(i.base()) ); 编辑 更新C ++ 11。 reverse_iterator i没有改变: m_CursorStack.erase( std::next(i). ...
-
没有PULLer的ZMQ PUSHer(ZMQ PUSHer with no PULLer)[2022-07-30]
你可以通过几种方式避免阻塞: 使用zmq_poll检查PUSH套接字何时可以输出,并且只有在准备就绪时才发送。 使用非阻塞发送(zmq_msg_send方法上的ZMQ_DONTWAIT) 将套接字上的发送超时设置为零(ZMQ_SNDTIMEO套接字选项),并在发送超时时处理错误返回 使用不同的套接字模式,例如ROUTER-DEALER以及从客户端到服务器更明确的信令 You can avoid blocking in several ways: Use zmq_poll to check when the ... -
可能的反向牵引器(Possible anticrawler)[2023-10-19]
我建议使用现有的数据集,这里有一些来自这个acl wiki页面的例子: 语料库: ... 牛津文本档案意大利报纸语料库 ...... ... 词汇网络 EuroWordNet MultiWordNet - 一个多语言词汇数据库,意大利语WordNet与普林斯顿WordNet 1.6严格对齐...... 请查看acl wiki页面上的完整列表,我认为你应该找到一个意大利语语料库,它可以让你定义意大利语单词。 I would suggest to use existing datasets, here are ... -
使用std::reverse_iterator : #include
#include int main() { const char* s = "abc"; std::reverse_iterator first(s + 3); std::reverse_iterator last(s); for( ; first != last; ++first) { std ... -
堆栈机器与反向波兰表示法(RPN)或波兰表示法(PN)之间没有直接连接。 你必须区分语法和语义 。 您可以在语法中说运算符应该在之前( add 3 5 ),( 3 add 5 )之间或之后( add 3 5 )它们的操作数,并且这些语法的语言看起来会有所不同。 面向堆栈的语言可以使用任何前缀/中缀/后缀形式来指定参数,我猜在这个意义上它们可以被分类为PN或RPN语言。 语言的语义 - 当表达式被评估时会发生什么 - 与语言的语法分离。 WebAssembly规范使用抽象堆栈机器来指示那些语义:对于每条指令, ...