简体   繁体   English

如何将ExecuteService与包含AutoCloseable资源的自定义线程一起使用

[英]How to use ExecuteService with custom Threads that contain a AutoCloseable resource

I present here a simplification of the problem I am trying to solve. 我在这里简化了我要解决的问题。 Summary of the classes I present: 我介绍的课程摘要:

  • Processor: is a non thread-safe class, that can be created without any arguments and needs to be closed when you are done using it. 处理器:是一个非线程安全的类,可以创建时不带任何参数,并且在使用完毕后需要关闭它。 Creating instances of this class is really expensive, so only one (per thread) should be created. 创建此类的实例确实非常昂贵,因此只能创建一个(每个线程)。 It provides methods to do certain operations. 它提供了执行某些操作的方法。
  • ResultProvider: is a thread-safe class that manages requests that needs a Processor to be handled. ResultProvider:是线程安全的类,用于管理需要处理Processor的请求。

The current implementation is similar to the following: 当前的实现类似于以下内容:

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

Now I want to make ResultProvider able to use several CPU cores. 现在,我想使ResultProvider能够使用多个CPU内核。 Ideally I would like to be able to use an ExecutorService to do this. 理想情况下,我希望能够使用ExecutorService来执行此操作。 Note that each Thread needs to instanciate its own Processor at start, and needs to .close() it when the Thread is to be deleated. 请注意,每个线程在启动时都需要实例化其自己的处理器,并且在委派该线程时需要将其关闭.close()。 The 'ExecutorService' should probable use a ThreadFactory that creates a custom Thread subclass which instanciates and closes an internal Processor. “ ExecutorService”应可能使用ThreadFactory来创建一个自定义Thread子类,以实例化并关闭内部Processor。

I think what I want would be something like this: 我想我想要的是这样的:

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);
    }
}

Now, is the feasible? 现在可行吗? I don't know how to implement this using as much of the Java concurrent classes as possible. 我不知道如何使用尽可能多的Java并发类来实现它。 Any advice? 有什么建议吗?

You don't need any custom thread. 您不需要任何自定义线程。 All you need is to create and submit a Callable that creates a processor, calls the function, and closes the processor: 您需要做的就是创建并提交一个Callable来创建处理器,调用该函数并关闭处理器:

public <T> T handle(Function<Processor, T> request) {
    Callable<T> callable = () -> {
        try(Processor processor = Processor.createNewProcessor()) {
            request.apply(processor);
        } 
    }
    return executor.submit(callable).get();
}

Note that synchronized is useless: the method doesn't use any mutable state. 请注意,synchronized是没用的:该方法不使用任何可变状态。

If you really want a single processor per thread, rather than a processor per callable, then you can use a custom factory as your question shows, except the processor would be obtained from a ThreadLocal (both in the custom thread and in the task). 如果确实要每个线程一个处理器,而不是每个可调用的处理器,那么可以使用问题所显示的自定义工厂,除非从ThreadLocal(在自定义线程和任务中)获得处理器。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM