대부분 Dave의 대답에 동의하지만 모든 "그룹"에서 CPU 시간을 슬라이스해야 할 경우 모든 작업 그룹이 병렬로 진행되어야합니다.
class TaskAllocator {
private final ConcurrentLinkedQueue<Queue<Runnable>> entireWork
= childQueuePerTaskGroup();
public Queue<Runnable> lockTaskGroup(){
return entireWork.poll();
}
public void release(Queue<Runnable> taskGroup){
entireWork.offer(taskGroup);
}
}
및
class DoWork implmements Runnable {
private final TaskAllocator allocator;
public DoWork(TaskAllocator allocator){
this.allocator = allocator;
}
pubic void run(){
for(;;){
Queue<Runnable> taskGroup = allocator.lockTaskGroup();
if(task==null){
//No more work
return;
}
Runnable work = taskGroup.poll();
if(work == null){
//This group is done
continue;
}
//Do work, but never forget to release the group to
// the allocator.
try {
work.run();
} finally {
allocator.release(taskGroup);
}
}//for
}
}
그런 다음 사용할 수 있습니다 유용한 구조의이 종류를 찾을 수 있습니다. ("잠금"으로 제거를 사용하여이 나는 그것이 더 많은 메모리를 사용하는 경향이 상상하지만 내 경우에는 괜찮 았는데) 실행할 최적 스레드 수 DoWork
태스크. 그것은
심지어
ConcurrentSkipListSet<MyQueue<Runnable>> sophisticatedQueue =
new ConcurrentSkipListSet(new SophisticatedComparator());
(실행 얻을하는 경향이 남아있는 많은 작업과 작업 그룹)
TaskAllocator
대신 간단한 큐의이를 이용하여,보다 정교한 뭔가를 할 수 .. 라운드 로빈로드 균형 종류의
SophisticatedComparator
이 간단한 방법은, 따라서 하위 작업이 순차적으로 실행하고, 하나 개의 슈퍼 작업에 모든 그룹의 작업을 "연결할"하는 것입니다
class SophisticatedComparator implements Comparator<MyQueue<Runnable>> {
public int compare(MyQueue<Runnable> o1, MyQueue<Runnable> o2){
int diff = o2.size() - o1.size();
if(diff==0){
//This is crucial. You must assign unique ids to your
//Subqueue and break the equality if they happen to have same size.
//Otherwise your queues will disappear...
return o1.id - o2.id;
}
return diff;
}
}
"하지만, 쓰레드는 서로를 차단하는 것입니다 및 처리량을 극대화하지 않습니다.". 개별 작업이 공유 된 데이터 구조 나 리소스에 액세스하고 이것이 경쟁의 원인이라는 것을 의미합니까? – Adamski
그룹의 모든 작업을 미리 알고 있습니까? 이는 솔루션을 선택할 때 중요합니다 (대기열 대 대기열 없음) –