java – 为什么ThreadPoolExecutor具有BlockingQueue作为参数?
我已经尝试创建并执行ThreadPoolExecutor
int poolSize = 2; int maxPoolSize = 3; ArrayBlockingQueue<Runnable> queue = new ArrayBlockingQueue<Runnable>(2); 如果我不断尝试第七,第八…任务 threadPool.execute(task); 队列达到最大大小后,它开始抛出“RejectedExecutionException”.意味着我没有加入这些任务. 那么这里BlockingQueue的作用是否缺少任务呢?意味着为什么不等待? 从BlockingQueue的定义
为什么我们不能去链接列表(正常的队列实现而不是阻塞队列)? 解决方法
出现此问题是因为您的任务队列太小,而这通过
execute方法的文档指示:
所以第一个问题是你把你的队列大小设置得很小: int poolSize = 2; int maxPoolSize = 3; ArrayBlockingQueue<Runnable> queue = new ArrayBlockingQueue<Runnable>(2); 然后你声明“如果[我]尝试第7,第8 …任务”,那么你会得到一个RejectedExecutionException,因为你超过队列的容量.有两种方法可以解决您的问题(我建议同时使用这两种方法): >增加队列的大小 你应该有一些这样的事情: public void ExecuteTask(MyRunnableTask task) { bool taskAdded = false; while(!taskAdded) { try { executor.execute(task); taskAdded = true; } catch (RejectedExecutionException ex) { taskAdded = false; } } } 现在,解决你的其他问题…
BlockingQueue的作用是完成Producer / Consumer模式,如果它足够大,那么您不应该看到遇到的问题.如上所述,您需要增加队列大小并捕获异常,然后重试执行任务.
链接列表既不是线程安全的也不是阻止的.生产者/消费者模式倾向于最好地使用阻塞队列. 更新 请不要因以下声明而受到冒犯,我有意使用更严格的语言,以强调您的第一个假设永远不应该是您使用的库出现问题(除非您写了图书馆自己,你知道有一个具体的问题)! 所以让我们现在休息一下:ThreadPoolExecutor和Java库都不是这里的问题.完全是您(误)使用图书馆造成问题. Javmex有一个great tutorial解释你所看到的确切情况. 你可能会有几个原因,为什么你比你排空更快填补队列? >正在添加执行任务的线程是加快它们的速度. 还有一些其他的原因,但我认为上述将是最常见的. 我会给你一个simple solution with an unbounded queue,但它不会解决你的(误)使用的图书馆.所以在我们指责Java库之前,让我们看看一个简明的例子来说明你遇到的确切问题. 更新2.0 以下是解决具体问题的其他几个问题: > ThreadPoolExecutor Block When Queue Is Full? (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |