Java 如何对包含自动关闭资源的自定义线程使用ExecuteService
我在这里对我试图解决的问题进行了简化。我介绍的课程摘要:Java 如何对包含自动关闭资源的自定义线程使用ExecuteService,java,multithreading,resources,threadpool,executor,Java,Multithreading,Resources,Threadpool,Executor,我在这里对我试图解决的问题进行了简化。我介绍的课程摘要: Processor:是一个非线程安全类,可以不带任何参数创建,并且在使用完后需要关闭它。创建此类的实例非常昂贵,因此只应创建一个(每个线程)。它提供了执行某些操作的方法 ResultProvider:是一个线程安全类,用于管理需要处理器处理的请求 当前实施类似于以下内容: class Processor implements AutoCloseable { (...) } class ResultProvider implement
- Processor:是一个非线程安全类,可以不带任何参数创建,并且在使用完后需要关闭它。创建此类的实例非常昂贵,因此只应创建一个(每个线程)。它提供了执行某些操作的方法
- ResultProvider:是一个线程安全类,用于管理需要处理器处理的请求
class Processor implements AutoCloseable { (...) }
class ResultProvider implements AutoCloseable {
private final Processor processor;
public ResultProvider() {
this.processor = Processor.createNewProcessor();
}
/*
* The 'request' doesn't turn a Procesoor into a T, it rather uses a Processor
* as a resource, to be able to compute a T
*/
public synchronized <T> T handle(Function<Processor, T> request) {
request.apply(processor);
}
public synchronized void close() {
processor.close();
}
}
类处理器实现自动关闭{(…)}
类ResultProvider实现自动关闭{
专用最终处理器;
公共结果提供者(){
this.processor=processor.createNewProcessor();
}
/*
*“请求”并没有把一个进程变成一个t,而是使用一个处理器
*作为一种资源,能够计算
*/
公共同步T句柄(函数请求){
请求。应用(处理器);
}
公共同步作废关闭(){
processor.close();
}
}
现在我想让ResultProvider能够使用几个CPU核。理想情况下,我希望能够使用ExecutorService来完成这项工作。
请注意,每个线程都需要在开始时实例化自己的处理器,并且在删除线程时需要.close()它。“ExecutorService”应该使用ThreadFactory创建自定义线程子类,该子类实例化并关闭内部处理器
我想我想要的是这样的东西:
class ResultProvider implements AutoCloseable {
private static class ProcessorThread extends Thread {
final private Processor processor = Processor.createNewProcessor();
public void run() {
try {
super.run();
} finally {
processor.close();
}
}
}
private final ExecutorService executor;
/*
* Not sure how to create one that uses my ProcessorThread and is able
* to be submitted Function<Processor, T> to get T...
*/
public ResultProvider() {
// ...
}
/*
* The 'request' doesn't turn a Procesoor into a T, it rather uses a Processor
* as a resource, to be able to compute a T
*/
public <T> T handle(Function<Processor, T> request) {
return executor.submit?(request).get();
}
public synchronized void close() {
executor.shutdown();
executor.awaitTermination(Long.MAX_VALUE, TimeUnit.DAYS);
}
}
类ResultProvider实现自动关闭{
私有静态类ProcessorThread扩展线程{
最终专用处理器=Processor.createNewProcessor();
公开募捐{
试一试{
super.run();
}最后{
processor.close();
}
}
}
私人最终执行人服务执行人;
/*
*不确定如何创建一个使用我的ProcessorRead并能够
*要提交函数以获取。。。
*/
公共结果提供者(){
// ...
}
/*
*“请求”并没有把一个进程变成一个t,而是使用一个处理器
*作为一种资源,能够计算
*/
公共T句柄(函数请求){
返回执行器.submit?(请求).get();
}
公共同步作废关闭(){
executor.shutdown();
执行人等待终止(长最大值,时间单位:天);
}
}
现在,这个方案可行吗?我不知道如何使用尽可能多的Java并发类来实现这一点。有什么建议吗?您不需要任何自定义线程。您只需创建并提交一个可调用函数,用于创建处理器、调用函数并关闭处理器:
public <T> T handle(Function<Processor, T> request) {
Callable<T> callable = () -> {
try(Processor processor = Processor.createNewProcessor()) {
request.apply(processor);
}
}
return executor.submit(callable).get();
}
公共T句柄(函数请求){
可调用可调用=()->{
try(Processor=Processor.createNewProcessor()){
请求。应用(处理器);
}
}
返回executor.submit(可调用).get();
}
请注意,synchronized是无用的:该方法不使用任何可变状态
如果您真的希望每个线程都有一个处理器,而不是每个可调用的处理器,那么您可以使用自定义工厂,正如您的问题所示,除了处理器将从ThreadLocal(在自定义线程和任务中)获得之外。我忘了说处理器创建非常昂贵,因此,理想情况下,我只希望在创建线程时创建处理器,而不是在发送请求时创建处理器。我将把这一点补充到我的答案中。正如你所说,我也会纠正同步的错误。我后来意识到了这一点。我已经修改了我的答案来解释如何实现这一点。ThreadLocal是我考虑的另一个解决方案。但是,如何确保那里的处理器在某个时候得到.close()'d?您在问题中提到的自定义ThreadFactory对我来说似乎是一个有效的解决方案。
return executor.submit(callable).get()
?如果要通过调用get
暂停当前线程,为什么不直接运行callable,即返回callable.call()
?