2017-11-16 9 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

タスクはタスクにゲッターを提供しないFutureTaskにラップされます。リフレクションを使って 'FutureTask'の' callable'フィールドにアクセスすることはできますが、それは非常に強固なアプローチではありません。 – assylias

+0

RejectedExecutionHandlerをオーバーライドし、自分自身を作成し​​ます。それが最善の方法です。 – canillas

+0

@canillasこれは、質問のコードで行われていることです。問題は、Runnableから基本となるTaskにアクセスする方法です。 – assylias

答えて

1

私はsubmitメソッドをオーバーライドしてFutureTaskクラスをオーバーライド:

は、ここに私のコードです!

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

関連する問題