java - Java 执行器框架中对终止线程的控制

标签 java multithreading executorservice thread-local

注意:我是英语新手,所以请原谅我的任何错误。

我使用线程本地来保存每个线程的资源;并在某些任务中使用它(线程本地)。我通过 java 执行器服务运行我的任务。当线程即将终止时,我会关闭我的资源;然后我需要在调用“executor.shoutdown”方法之后通过执行程序服务在所有创建的线程中运行一个任务。我如何强制执行器在每个线程上运行一个任务,当它终止这些任务时?

import java.util.concurrent.*;

public class Main2 {

    public static void main(String[] args) {

        ExecutorService executor = new ForkJoinPool(3);
        SimpleValue val = new SimpleValue();
        for(int i=0; i<1000; i++){
            executor.execute(new Task(val));
        }

        executor.shutdown();
        while( true ) {
            try {
                if( executor.awaitTermination(1, TimeUnit.SECONDS) ) System.exit(0);
            } catch(InterruptedException intrExc) {
                // continue...
            }
        }
    }

    protected static interface ResourceProvider<T>
    extends AutoCloseable {
        public T get();
        public ResourceProvider<T> reset() throws Exception;
        public ResourceProvider<T> reset(boolean force) throws Exception;
        public void close();
    }

    protected static abstract class ThreadLocalResourceProvider<T>
    extends ThreadLocal<T>
    implements ResourceProvider<T> {}

    protected static class SimpleValue
    extends ThreadLocalResourceProvider<String> {
        public String initialValue() {
            return "Hello " + Thread.currentThread().getName();
        }
        public SimpleValue reset() throws Exception {
            return reset(false);
        }
        public SimpleValue reset(boolean force) throws Exception{
            set(this.initialValue());
            return this;
        }
        public void close() {
            remove();
        }
    }

    protected static class Task
    implements Runnable {

        protected SimpleValue val;
        public Task(SimpleValue val) {
            this.val = val;
        }

        @Override
        public void run() {
            try {
                System.out.print(val.reset().get());
            } catch( Exception exc ) {
                System.out.print( exc.getMessage() );
            }
        }
    }

}

最佳答案

大多数执行器都可以使用 ThreadFactory 来构造。 ForkJoinPool 也是如此。不过,为了简化起见,我使用了不同的 ExecutorService。

ExecutorService executor = Executors.newFixedThreadPool(
    10, new FinalizerThreadFactory(Executors.defaultThreadFactory()));

FinalizerThreadFactory将线程的创建委托(delegate)给传递的线程工厂。但是,它创建的线程将在退出之前执行一些附加代码。这很简单:

class FinalizerThreadFactory implements ThreadFactory {
    private final ThreadFactory delegate;
    public FinalizerThreadFactory(ThreadFactory delegate) {
        this.delegate = delegate;
    }
    public Thread newThread(final Runnable r) {
        return delegate.newThread(new Runnable() {
            public void run() {
                try {
                    r.run();
                } finally {
                    // finalizer code goes here.
                }
            }
        });
    }
}

关于java - Java 执行器框架中对终止线程的控制,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23557550/

相关文章:

java - Java中高效的多线程数组构建

multithreading - Perl队列和线程异常退出

java - 固定线程池执行器受到某些终止条件的限制

java - ExecutorService 变慢,使我的电脑陷入困境

java - 有没有办法通过 Sonar 或 Hudson 获得准确的测试计数?

java - 索引超出范围

JavaFX VBox 布局

Java——等待方法未退出

Java ExecutorsService 提交一个 FutureTask 获取 Future 返回 null

java - 使用 spring-security 和来自 websocket 消息的访问主体来保护 Spring-Websocket