2012-10-04 34 views
14

Tôi đã tìm kiếm rất nhiều nhưng không thể tìm thấy bất kỳ giải pháp nào. Tôi sử dụng hồ bơi chuỗi java theo cách như vậy:Chỉ định thực hiện lệnh công việc trong Java

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

Theo cách như vậy Nhiệm vụ được thực hiện theo thứ tự sau đó (như xếp hàng). Nhưng tôi cần thay đổi chiến lược "chọn công việc tiếp theo". Vì vậy, tôi muốn gán cho mỗi nhiệm vụ xác định ưu tiên (nó không phải là ưu tiên luồng) và thực hiện các nhiệm vụ tương ứng với các ưu tiên này. Vì vậy, khi người thực thi đã hoàn thành một nhiệm vụ khác, nó chọn tác vụ tiếp theo là nhiệm vụ có mức độ ưu tiên tối đa. Nó mô tả vấn đề chung. Có thể có cách tiếp cận đơn giản hơn, không tính đến các ưu tiên. Nó chọn nhiệm vụ được thêm vào cuối cùng bên cạnh thực thi thay vì thêm lần đầu tiên. Nói chung FixedThreadPool sử dụng chiến lược FIFO. Tôi có thể sử dụng chiến lược LIFO ví dụ không?

Trả lời

11

Bạn có thể sử dụng để xác định PriorityBlockingQueue Queue để ThreadPoolExecutor.

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

Xác định ComparableFutureTask để so sánh về Mức độ ưu tiên.

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 có thể cung cấp một đoạn trích để cải thiện điều này. – Tudor

+5

Điều này không thể làm việc vì 'newTaskFor' sẽ bọc ComparableFutureTask vào trong FutureTask, không thể so sánh được. Bạn cũng cần ghi đè lên hai phương thức 'newTaskFor'. – assylias

+1

Xem [bài đăng này] (http://stackoverflow.com/a/16834473/829571) cho một ví dụ đơn giản. – assylias

7

ThreadPoolExecutor constructor accept BlockingQueue. Bạn có thể chuyển hàng đợi dưới dạng PriorityBlockingQueue. Nó không thực hiện bất kỳ người được cấp trên đặt hàng bạn cần phải vượt qua so sánh tùy chỉnh để duy trì trật tự.

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

Bài đăng tốt ngoại trừ 'bằng' trả về 'boolean' và' so sánh' trả về 'int' . Tôi nghĩ bạn có ý định sử dụng 'compareTo'. – Tudor

+0

+1 cảm ơn thông báo. –

Các vấn đề liên quan