Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/typo3/2.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多线程环境中管理正在运行的任务的Singleton类_Java_Concurrency_Singleton_Threadpool - Fatal编程技术网

用于在Java多线程环境中管理正在运行的任务的Singleton类

用于在Java多线程环境中管理正在运行的任务的Singleton类,java,concurrency,singleton,threadpool,Java,Concurrency,Singleton,Threadpool,我的情况与本问题中描述的类似: 因为我有一个阻塞队列,它获取fed命令(ICommandTask扩展了可调用的{Object}),线程池从中启动并运行。阻塞队列提供了调用线程和执行线程之间的线程同步和隔离。整个程序中的不同对象可以将ICommandTasks提交到命令队列,这就是我将AddTask()设置为静态的原因 import java.util.concurrent.BlockingQueue; 导入java.util.concurrent.ExecutorService; 导入java

我的情况与本问题中描述的类似:

因为我有一个阻塞队列,它获取fed命令(ICommandTask扩展了可调用的{Object}),线程池从中启动并运行。阻塞队列提供了调用线程和执行线程之间的线程同步和隔离。整个程序中的不同对象可以将ICommandTasks提交到命令队列,这就是我将AddTask()设置为静态的原因

import java.util.concurrent.BlockingQueue;
导入java.util.concurrent.ExecutorService;
导入java.util.concurrent.Executors;
导入java.util.concurrent.LinkedBlockingQueue;
导入com.mypackage.tasks.ICommandTask;
公共枚举命令队列
{
实例;
私有最终阻塞队列命令队列;
私人最终执行人服务执行人;
私有命令队列()
{
commandQueue=新建LinkedBlockingQueue();
executor=Executors.newCachedThreadPool();
}
公共静态void start()
{
新线程(INSTANCE.new WaitForProducers()).start();
}
公共静态void addTask(ICommandTask命令)
{
INSTANCE.commandQueue.add(命令);
}
私有类WaitForProducers实现Runnable
{
@凌驾
公开募捐
{
ICommandTask命令;
while(true)
{
尝试
{
command=INSTANCE.commandQueue.take();
执行人提交(任务);
}
捕捉(中断异常e)
{
//伐木等。
}
}   
}
}
}
在启动期间的主程序中,使用以下命令启动命令队列:创建新的CommandQueue对象,并在单独的线程中启动WaitForProducer

CommandQueue.Start();
我想问,使用singleton enum(以便程序的不同部分可以访问)将多个生产者设置为单个执行者,并使用单独的线程从队列中取出任务并提交到线程池,这种方法是否是我想要实现的推荐方法。特别是在非常多线程的环境中

到目前为止,它似乎工作正常,但我计划创建类似的对象到CommandQueue来处理不同类型的任务。它们将存储在自己的队列中。例如OrderQueue、EventQueue、NegotiationQueue等,因此它需要具有一定的可伸缩性和线程安全性


提前感谢。

出于兴趣,为什么要忽略方法的Java命名约定?这将使其他Java开发人员更难阅读您的代码。Hi Jon,您是说对方法名等使用大写字母吗?你可能知道我来自C#背景。这对我来说比较容易,但你让别人更难的想法是对的。我会编辑它。thanksIt似乎为此做了很多工作,正如您可能知道的,单身并不总是理想的,尤其是在测试方面。为什么不简单地将生产者更改为在其构造函数中接受executor参数并自己调用executor.submit(命令)?(换句话说,将执行者用作队列)@assylias,谢谢你的建议。我理解你现在所说的单身和测试。我唯一的问题是,通常情况下,任务以突发方式出现,因此队列有助于平滑池中的负载。我意识到我可以将阻塞队列直接送入ThreadPoolExecutor,而不需要单独的线程来读取队列。我也不必担心被拒绝的执行例外。singleton更为方便,但试着替换instanceI,我得到了“Java并发性实践”的支持,这似乎是非常推荐的(我现在是一个粉丝)。它解释了由Executors工厂生成的主ThreadPoolExecutor(newCachedThreadPool等)有自己的内置同步队列,因此完全不需要使用单独的队列来存储带有newCachedThreadPool的任务。当然,我可以通过直接创建ThreadPoolExecutor来调整执行策略,如果我愿意,可以使用阻塞队列。