2012-10-04 5 views
14

많이 검색했지만 해결 방법을 찾을 수 없습니다. 나는 그런 식으로 자바 스레드 풀을 사용 : 같은 방법으로 작업에Java에서 작업 순서 실행을 지정하십시오.

ExecutorService c = Executors.newFixedThreadPool(3); 
for (int i = 0; i < 10; ++i) { 
    c.execute(new MyTask(i)); 
} 

은 필연적 인 순서대로 실행됩니다 (큐와 같이). 그러나 나는 "다음 작업 선택"전략을 변경해야합니다. 따라서 각 작업에 우선 순위 (스레드 우선 순위가 아님)를 지정하고 이러한 우선 순위에 해당하는 작업을 실행하려고합니다. 따라서 executor가 다른 task를 마치면 다음 task를 최대 우선 순위의 task로 선택한다. 일반적인 문제를 설명합니다. 어쩌면 우선 순위를 설명하지 않는 더 간단한 접근법이있을 수 있습니다. 첫 번째 추가 대신 마지막으로 추가 된 작업을 다음 실행으로 선택합니다. 대략 FixedThreadPool은 FIFO 전략을 사용합니다. 예를 들어 LIFO 전략을 사용할 수 있습니까?

답변

11

당신을 도와줍니다.

public class PriorityExecutor extends ThreadPoolExecutor { 

    public PriorityExecutor(int corePoolSize, int maximumPoolSize, 
      long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue) { 
     super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue); 
    } 
    //Utitlity method to create thread pool easily 
    public static ExecutorService newFixedThreadPool(int nThreads) { 
     return new PriorityExecutor(nThreads, nThreads, 0L, 
       TimeUnit.MILLISECONDS, new PriorityBlockingQueue<Runnable>()); 
    } 
    //Submit with New comparable task 
    public Future<?> submit(Runnable task, int priority) { 
     return super.submit(new ComparableFutureTask(task, null, priority)); 
    } 
    //execute with New comparable task 
    public void execute(Runnable command, int priority) { 
     super.execute(new ComparableFutureTask(command, null, priority)); 
    } 
} 

우선 순위를 비교하려면 ComparableFutureTask을 정의하십시오.

class ComparableFutureTask<T> extends FutureTask<T> 
     implements 
      Comparable<ComparableFutureTask<T>> { 

    volatile int priority = 0; 

    public ComparableFutureTask(Runnable runnable, T result, int priority) { 
     super(runnable, result); 
     this.priority = priority; 
    } 
    public ComparableFutureTask(Callable<T> callable, int priority) { 
     super(callable); 
     this.priority = priority; 
    } 
    @Override 
    public int compareTo(ComparableFutureTask<T> o) { 
     return Integer.valueOf(priority).compareTo(o.priority); 
    } 
    } 
+0

+1을 사용하면이 기능을 향상시킬 수 있습니다. – Tudor

+5

'newTaskFor'가 ComparableFutureTask를 FutureTask로 래핑 할 것이기 때문에 이것은 작동하지 않습니다. 또한 두 개의 newTaskFor 메소드를 오버라이드해야한다. – assylias

+1

단순한 예를 보려면 [this post] (http://stackoverflow.com/a/16834473/829571)를 참조하십시오. – assylias

7

ThreadPoolExecutor 생성자는 BlockingQueue를 허용합니다. 대기열을 PriorityBlockingQueue로 전달할 수 있습니다. 주문을 수주하기 위해 수작업 비교자를 전달해야하는 수혜자는 없습니다.

static BlockingQueue<Task> queue=new PriorityBlockingQueue<Task>(MAXPOOL,new TaskComparator()); 

static ThreadPoolExecutor threadpool = new ThreadPoolExecutor(30, MAXPOOL, 
     MAXPOOL, TimeUnit.SECONDS, (PriorityBlockingQueue) queue, new mThreadFactory()); 



class TaskComparator implements Comparator<Task>{ 
    public int compare(Task t1, Task t2){ 
    //write you own logic to compare two task. 
    } 
} 
+1

'평등'이 '부울'을 반환하고 '비교'가 'int'를 반환한다는 점을 제외하면 좋은 게시물입니다. . 나는 당신이'compareTo '를 사용하려고 생각했다. – Tudor

+0

+1 고지를 보내 주셔서 감사합니다. –