注意:我是英语新手,所以请原谅我有任何错误。
我使用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() );
}
}
}
}
答案 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.
}
}
});
}
}