यहां विचार यह है कि निष्पादक में प्राथमिकताब्लॉकिंग क्यूयू का उपयोग करना है। इसके लिए:
- एक तुलनात्मक बनाएं जो हमारे वायदा की तुलना करेगा।
- प्राथमिकता रखने के लिए भविष्य के लिए प्रॉक्सी बनाएं।
- हमारे प्रॉक्सी में हर भविष्य को लपेटने के लिए 'newTaskFor' को ओवरराइड करें।
सबसे पहले आप अपने भविष्य पर प्राथमिकता पकड़ की जरूरत है:
class PriorityFutureComparator implements Comparator<Runnable> {
public int compare(Runnable o1, Runnable o2) {
if (o1 == null && o2 == null)
return 0;
else if (o1 == null)
return -1;
else if (o2 == null)
return 1;
else {
int p1 = ((PriorityFuture<?>) o1).getPriority();
int p2 = ((PriorityFuture<?>) o2).getPriority();
return p1 > p2 ? 1 : (p1 == p2 ? 0 : -1);
}
}
}
अगला मान लेते हैं कि हम एक डालते हैं:
class PriorityFuture<T> implements RunnableFuture<T> {
private RunnableFuture<T> src;
private int priority;
public PriorityFuture(RunnableFuture<T> other, int priority) {
this.src = other;
this.priority = priority;
}
public int getPriority() {
return priority;
}
public boolean cancel(boolean mayInterruptIfRunning) {
return src.cancel(mayInterruptIfRunning);
}
public boolean isCancelled() {
return src.isCancelled();
}
public boolean isDone() {
return src.isDone();
}
public T get() throws InterruptedException, ExecutionException {
return src.get();
}
public T get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException {
return src.get();
}
public void run() {
src.run();
}
}
इसके बाद आप तुलनित्र कि सही ढंग से प्राथमिकता वायदा सॉर्ट हैं परिभाषित करने की जरूरत इस तरह की लंबी नौकरी:
class LenthyJob implements Callable<Long> {
private int priority;
public LenthyJob(int priority) {
this.priority = priority;
}
public Long call() throws Exception {
System.out.println("Executing: " + priority);
long num = 1000000;
for (int i = 0; i < 1000000; i++) {
num *= Math.random() * 1000;
num /= Math.random() * 1000;
if (num == 0)
num = 1000000;
}
return num;
}
public int getPriority() {
return priority;
}
}
फिर क्रम प्राथमिकता में इन नौकरियों पर अमल करने में कोड दिखेगा की तरह:
public class TestPQ {
public static void main(String[] args) throws InterruptedException, ExecutionException {
int nThreads = 2;
int qInitialSize = 10;
ExecutorService exec = new ThreadPoolExecutor(nThreads, nThreads, 0L, TimeUnit.MILLISECONDS,
new PriorityBlockingQueue<Runnable>(qInitialSize, new PriorityFutureComparator())) {
protected <T> RunnableFuture<T> newTaskFor(Callable<T> callable) {
RunnableFuture<T> newTaskFor = super.newTaskFor(callable);
return new PriorityFuture<T>(newTaskFor, ((LenthyJob) callable).getPriority());
}
};
for (int i = 0; i < 20; i++) {
int priority = (int) (Math.random() * 100);
System.out.println("Scheduling: " + priority);
LenthyJob job = new LenthyJob(priority);
exec.submit(job);
}
}
}
इस कोड का एक बहुत कुछ है, लेकिन है कि लगभग एक ही तरीका है यह पूरा किया जा सकता है।
मेरी मशीन पर आउटपुट निम्नलिखित की तरह है:
Scheduling: 39
Scheduling: 90
Scheduling: 88
Executing: 39
Scheduling: 75
Executing: 90
Scheduling: 15
Scheduling: 2
Scheduling: 5
Scheduling: 24
Scheduling: 82
Scheduling: 81
Scheduling: 3
Scheduling: 23
Scheduling: 7
Scheduling: 40
Scheduling: 77
Scheduling: 49
Scheduling: 34
Scheduling: 22
Scheduling: 97
Scheduling: 33
Executing: 2
Executing: 3
Executing: 5
Executing: 7
Executing: 15
Executing: 22
Executing: 23
Executing: 24
Executing: 33
Executing: 34
Executing: 40
Executing: 49
Executing: 75
Executing: 77
Executing: 81
Executing: 82
Executing: 88
Executing: 97
+1 PriorityBlockingQueue जाने का रास्ता है। आप एक तुलनात्मक को कार्यान्वित कर सकते हैं या कार्यों को खुद को तुलनात्मक बना सकते हैं। –
यह आलेख एक महान संदर्भ है: http://binkley.blogspot.fr/2009/04/jumping-work-queue-in-executor.html – Snicolas
मेरा समाधान प्राथमिकता से कार्यों का आदेश देता है, लेकिन समान प्राथमिकता स्तर पर आदेश सबमिट करना: http://stackoverflow.com/a/42831172/1386911 –