2014-05-09 2 views
2

참고 : 영어를 처음 사용하기에이 언어가 잘못되었음을 용서하십시오.Java의 종료 스레드에 대한 제어 Executor-framework

스레드 당 리소스를 저장하기 위해 스레드 로컬을 사용합니다. 일부 작업에서는 스레드 로컬로 사용하십시오. Java Executor-Service로 작업을 실행합니다. 스레드가 종료 될 때 리소스를 닫습니다. "executor.shoutdown"메소드를 호출 한 후에 executor-service가 작성한 모든 스레드에서 태스크를 실행해야한다. 스레드를 종료 할 때 실행 프로그램이 스레드별로 작업을 실행하도록 강제 할 수 있습니까?

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

} 

답변

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

내가 forkjoinpool 대한 코드를 작성 [요지 (https://gist.github.com/reza-samee/f3ac9ddfd9ec7a60cced); @nosid 덕분에 –