Java 使用newFixedThreadPool的多线程程序不';当线程池大小小于已执行的任务数时,不能作为例外运行
我在这里做错了什么?要修复该行为,您需要执行以下操作之一:Java 使用newFixedThreadPool的多线程程序不';当线程池大小小于已执行的任务数时,不能作为例外运行,java,multithreading,concurrency,executorservice,Java,Multithreading,Concurrency,Executorservice,我在这里做错了什么?要修复该行为,您需要执行以下操作之一: 具有足够的可运行程序,每个可运行程序都具有足够的队列容量以容纳所有1000条消息(例如:100个可运行程序,容量为10条或更多;或10个可运行程序,容量为100条或更多),或 有一个足够大的线程池来容纳所有可运行的线程,这样每个线程都可以开始运行 如果没有这些情况,ExecutorService将不会启动额外的可运行程序。主工作线程将继续向每个队列添加项目,包括非运行可运行程序的项目,直到遇到一个已满的队列,此时它将阻塞该队列。有1
- 具有足够的可运行程序,每个可运行程序都具有足够的队列容量以容纳所有1000条消息(例如:100个可运行程序,容量为10条或更多;或10个可运行程序,容量为100条或更多),或
- 有一个足够大的线程池来容纳所有可运行的线程,这样每个线程都可以开始运行
noOfProcess=10
和线程池大小=5
,如下所示:newlinkedblockingqueue(100)
如果更改此行,您可以观察到此行为–非运行Runnable的队列已满:
processes.get(roundRobinIndex++).getElements().put(i);
对此(这是相同的逻辑代码,但保存了对象引用以供在println()
输出中使用):
MyRunnable=processs.get(roundRobinIndex++);
BlockingQueue elements=runnable.getElements();
System.out.println(“尝试将“+runnable.getTaskName()+”的put()与“+elements.size()+”elements一起放置”);
要素。付诸表决(i);
要修复该行为,您需要执行以下操作之一:
- 具有足够的可运行程序,每个可运行程序都具有足够的队列容量以容纳所有1000条消息(例如:100个可运行程序,容量为10条或更多;或10个可运行程序,容量为100条或更多),或
- 有一个足够大的线程池来容纳所有可运行的线程,这样每个线程都可以开始运行
noOfProcess=10
和线程池大小=5
,如下所示:newlinkedblockingqueue(100)
如果更改此行,您可以观察到此行为–非运行Runnable的队列已满:
processes.get(roundRobinIndex++).getElements().put(i);
对此(这是相同的逻辑代码,但保存了对象引用以供在println()
输出中使用):
MyRunnable=processs.get(roundRobinIndex++);
BlockingQueue elements=runnable.getElements();
System.out.println(“尝试将“+runnable.getTaskName()+”的put()与“+elements.size()+”elements一起放置”);
要素。付诸表决(i);
啊,是的。好的僵局
发生的情况是:您向ExecutorService提交10个任务,然后通过.put(i)
发送作业。当任务5的队列已满时,这将按预期阻止任务5。现在任务5当前没有执行,事实上也永远不会执行,因为任务0到4仍在阻塞您的FixedThreadPool,阻塞在运行()方法中的take()
等待来自的新作业。put(i)
,它们永远不会得到新作业
这个错误是代码中的一个基本设计缺陷,有无数种方法可以修复它,其中之一就是增加线程池大小
我的建议是,您回到绘图板,重新思考主方法中的结构
既然你发布了你的代码,有一些提示:
1.:
发布您的整个代码可以解释为对“请修复我的代码”的调用,并鼓励您忽略所有不必要的细节(如所有的getter和setter)。也许检查一下
2.:
在同一个主体中发布两个类使事情变得有点复杂。下次再分吧
3.:(挑剔)
processs.get(roundRobinIndex++).getElements().put(i)代码>
像您在这里所做的那样组合两个操作是一种糟糕的风格,因为它会使您的代码对其他人的可读性降低。你可以写下:
processs.get(i%noOfProcesses.getElements().put(i)代码>啊
processes.get(roundRobinIndex++).getElements().put(i);
MyRunnable runnable = processes.get(roundRobinIndex++);
BlockingQueue<Integer> elements = runnable.getElements();
System.out.println("attempt to put() for " + runnable.getTaskName() + " with " + elements.size() + " elements");
elements.put(i);