在Java Executor框架中控制终止线程

时间:2014-05-09 05:58:28

标签: java multithreading executorservice thread-local

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

我使用thread-local来保存每个线程的资源;并在某些任务中使用它(线程本地)。我通过java executor-service运行我的任务。当一个线程要终止时,我会关闭我的资源;然后我需要在所有创建的线程中通过executor-service运行一个任务,之后我调用“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() );
            }
        }
    }

}

1 个答案:

答案 0 :(得分:4)

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

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

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

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