2017-11-16 3 views
1

executor에 의해 거부 된 Task을 알고 싶습니다. 예를 들어, 거부 된 작업의 이름을 얻고 싶습니다. 그러나 RejectedExecutionHandler에서이 작업을 수행 할 수 없습니다!RejectedExecutionHandler에서 작업 필드를 가져 오는 방법은 무엇입니까?

public static void main(String[] args) throws Exception{ 
    ThreadPoolExecutor executor = new ThreadPoolExecutor(1, 1, 1L, TimeUnit.SECONDS, new SynchronousQueue<Runnable>(), 
      (Runnable r, ThreadPoolExecutor executor1) -> { 
       //TODO 
       //want to get the task name 
       System.out.println("in reject:"); 
    }); 
    Task t1 = new Task("t1"); 
    Task t2 = new Task("t2"); 
    Future<Integer> t1Fe = executor.submit(t1); 
    Future<Integer> t2Fe = executor.submit(t2); 

    System.out.println(t1Fe.get()); 
    System.out.println(t2Fe.get()); 
} 

static class Task implements Callable{ 
    private String name; 

    public Task(String name) { 
     this.name = name; 
    } 

    @Override 
    public Object call() throws Exception { 
     try { 
      Thread.sleep(1000); 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 
     System.out.println(1); 
     return name; 
    } 
} 
+0

작업은 작업에 getter를 제공하지 않는 FutureTask로 래핑됩니다. 리플렉션을 사용하여'FutureTask'의'callable' 필드에 접근 할 수는 있지만 매우 견고한 접근 방법은 아닙니다. – assylias

+0

RejectedExecutionHandler를 재정의하고 자신을 만드십시오. 가장 좋은 방법입니다. – canillas

+0

@canillas 그 질문의 코드에서 수행 된 작업입니다. 문제는 Runnable에서 기본 작업에 액세스하는 방법입니다. – assylias

답변

1

나는 submit 방법을 무시하고 FutureTask 클래스를 오버라이드 (override) :

여기 내 코드입니다!

public static void main(String[] args) throws Exception{ 
    ThreadPoolExecutor executor = new ThreadPoolExecutor(1, 1, 1L, TimeUnit.SECONDS, new SynchronousQueue<Runnable>(), 
      (Runnable r, ThreadPoolExecutor executor1) -> { 
       //TODO 
       //want to get the task name 
       MyFutureTask task = (MyFutureTask)r; 
       System.out.println("in reject:"+task.name); 
    }); 
    Task t1 = new Task("t1"); 
    Task t2 = new Task("t2"); 
    Future<Integer> t1Fe = submit(executor,t1); 
    Future<Integer> t2Fe = submit(executor,t2); 

    System.out.println(t1Fe.get()); 
    System.out.println(t2Fe.get()); 
} 

public static Future submit(ThreadPoolExecutor executor,Callable task) { 
    if (task == null) throw new NullPointerException(); 
    MyFutureTask ftask = new MyFutureTask(task); 
    ftask.setName(((Task)task).name); 
    executor.execute(ftask); 
    return ftask; 
} 

static class MyFutureTask extends FutureTask{ 
    private String name; 
    public MyFutureTask(Callable callable) { 
     super(callable); 
    } 

    public String getName() { 
     return name; 
    } 

    public void setName(String name) { 
     this.name = name; 
    } 
} 
static class Task implements Callable{ 
    private String name; 

    public Task(String name) { 
     this.name = name; 
    } 

    @Override 
    public Object call() throws Exception { 
     try { 
      Thread.sleep(1000); 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 
     System.out.println(1); 
     return name; 
    } 
} 
+0

멋지게 완료되었습니다 - 대안으로 ThreadPoolExecutor를 확장하고 3 개의 submit 메소드를 오버라이드 할 수 있습니다. – assylias

+2

@assylias : better, ['newTaskFor'] (https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/AbstractExecutorService.html#newTaskFor-java.util.concurrent.Callable)를 재정의하십시오. -)이 목적을 위해 정확하게 만들어진 것입니다. 그럼, 모든'submit' 메소드를 오버라이드 할 필요가 없으며 이후 버전이 오버라이드하지 않은 추가적인 제출 메소드를 제공 할 수도 있다는 것을 두려워하지 않는다. – Holger

관련 문제