Cercherò di spiegare questo problema con un codice completamente funzionale. Ma prima di tuffarsi nel codice Vorrei spiegare circa PriorityBlockingQueue
PriorityBlockingQueue: PriorityBlockingQueue è un'implementazione del BlockingQueue. Accetta le attività insieme alla loro priorità e invia l'attività con la massima priorità per l'esecuzione. Se due attività hanno la stessa priorità, è necessario fornire alcune regole personalizzate per decidere quale attività deve essere eseguita per prima.
Ora consente di accedere al codice immediatamente.
Classe driver: questa classe crea un executor che accetta le attività e successivamente le invia per l'esecuzione. Qui creiamo due task uno con priorità LOW e l'altro con priorità HIGH. Qui diciamo all'esecutore di eseguire un MAX di 1 thread e utilizzare PriorityBlockingQueue.
public static void main(String[] args) {
/*
Minimum number of threads that must be running : 0
Maximium number of threads that can be created : 1
If a thread is idle, then the minimum time to keep it alive : 1000
Which queue to use : PriorityBlockingQueue
*/
PriorityBlockingQueue queue = new PriorityBlockingQueue();
ThreadPoolExecutor executor = new ThreadPoolExecutor(0,1,
1000, TimeUnit.MILLISECONDS,queue);
MyTask task = new MyTask(Priority.LOW,"Low");
executor.execute(new MyFutureTask(task));
task = new MyTask(Priority.HIGH,"High");
executor.execute(new MyFutureTask(task));
task = new MyTask(Priority.MEDIUM,"Medium");
executor.execute(new MyFutureTask(task));
}
classe MyTask: MyTask implementa Runnable e accetta come argomento prioritario nel costruttore. Quando viene eseguita questa attività, stampa un messaggio e quindi mette il thread in stop per 1 secondo.
public class MyTask implements Runnable {
public int getPriority() {
return priority.getValue();
}
private Priority priority;
public String getName() {
return name;
}
private String name;
public MyTask(Priority priority,String name){
this.priority = priority;
this.name = name;
}
@Override
public void run() {
System.out.println("The following Runnable is getting executed "+getName());
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
classe MyFutureTask: Dal momento che stiamo usando PriorityBlocingQueue per tenere i nostri compiti, i nostri compiti deve essere avvolto all'interno FutureTask e la nostra implementazione di FutureTask deve implementare l'interfaccia Comparable. L'interfaccia Comparable confronta la priorità di 2 diverse attività e invia l'attività con la massima priorità per l'esecuzione.
public class MyFutureTask extends FutureTask<MyFutureTask>
implements Comparable<MyFutureTask> {
private MyTask task = null;
public MyFutureTask(MyTask task){
super(task,null);
this.task = task;
}
@Override
public int compareTo(MyFutureTask another) {
return task.getPriority() - another.task.getPriority();
}
}
Classe di priorità: Si spiega da sé Classe di priorità.
public enum Priority {
HIGHEST(0),
HIGH(1),
MEDIUM(2),
LOW(3),
LOWEST(4);
int value;
Priority(int val) {
this.value = val;
}
public int getValue(){
return value;
}
}
Ora, quando si corre questo esempio, si ottiene il seguente output
The following Runnable is getting executed High
The following Runnable is getting executed Medium
The following Runnable is getting executed Low
Anche se abbiamo presentato la bassa priorità prima, ma ad alto compito prioritario tardi, ma dal momento che stiamo utilizzando un PriorityBlockingQueue, qualsiasi l'attività con una priorità più alta verrà eseguita per prima.
Interessante domanda. A mio parere, questo sembra un po 'di supervisione nell'API. –
Se dovessi indovinare perché non fa parte dell'API, direi che probabilmente è perché il problema della fame è difficile. Avrebbero bisogno di fornire una nuova serie di primitivi per l'equità e l'escalation; cose come must-execute-by e may-be-indefinitely-deferred (nota che sto tirando fuori questi nomi dal mio culo). Potrei desiderare che l'abbiano fatto, ma non li biasimo :) –
Sì, questo ha senso. Sembra che sarebbe una buona cosa avere, però, ma quando pensi di dover essenzialmente scrivere un algoritmo di programmazione della CPU in Java probabilmente stai facendo qualcosa di sbagliato. –