Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.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 如何对包含自动关闭资源的自定义线程使用ExecuteService_Java_Multithreading_Resources_Threadpool_Executor - Fatal编程技术网

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()