2012-05-07 2 views
0

tasks이라고하는 LinkedBlockingQueue이 있는데, tasks.take()을 호출하고 작업을 사용할 수있을 때까지 기다릴 때 CPU 사용량은 100 %입니다. tasks.take() 메서드를 사용하는 스레드가 여러 개 있습니다 (모든 스레드마다 자체 tasks 변수가 있음). 왜 이런 일이 일어나는 지 아는 사람이 있습니까? tasks 변수큰 CPU 영향 LinkedBlockingQueue

private LinkedBlockingQueue<ComputerTask> tasks; 
// snip 
this.tasks = new LinkedBlockingQueue<ComputerTask>(100); 

코드의

Defenition는 새 작업

this.tasks.offer(task); 
에게 제공

ComputerTask task = tasks.take(); 

코드 작업을하는

P.S. 이 Java 버전에 문제가 있는지 알지 못합니다. 다른 컴퓨터에서 아직 테스트하지 않았기 때문입니다.

java version "1.6.0_31" 
Java(TM) SE Runtime Environment (build 1.6.0_31-b04-413-11M3623) 
Java HotSpot(TM) 64-Bit Server VM (build 20.6-b01-413, mixed mode) 
+0

아마도 작업을 수행하는 것이 없으며 대기열이 비어 있습니다. 그렇습니까? 그렇다면 분명히 루핑하는 소비자 스레드 일 것입니다. –

+0

예. 대기열이 비어 있습니다. 0.2 초마다 채워지지 않습니다. 몇 분 후에 다시 채워질 수 있습니다. 그때는 문제 죠? 그러나 그것은 프로그램의 중요한 부분이므로, 나는 그것을 정말로 꺼낼 수는 없습니다. 어떤 추천? – Robbietjuh

+0

@Robbietjuh 증가 된 CPU의 위치를 ​​평가하는 것이 좋습니다. 예를 들어, 생산자가 전혀없는 상태에서 10 개의 스레드를 테이크 할 수 있습니다. 그래도 여전히 CPU가 증가했다면 다른 곳에서는 문제가 발생합니다 (다른 기능이없는 간단한 앱을 작성한다는 것을 증명하기 위해). 표준 JDK를 사용하고 단순히 LBQ를 'take'하는 경우에는 CPU 사용이 없습니다. –

답변

2

나는 내 의견을 답으로 바꿀 것입니다.

tasks.take();은 많은 수의 항목을 큐에서 제외하지 않는 한 회전하지 않아야합니다. 큐가 비어 있으면 차단 될 것이므로 이 아닌 것으로 의심됩니다.은 100 %로드의 원인입니다. 나는 프로파일 러를 사용하거나 take() 주위에 디버그 명령문을 추가하여 많은 시간 동안 호출되는지 확인합니다.

큐브가 가득 차면 tasks.offer(task)은 즉시 false을 반환한다는 점을 기억하십시오. 대신 블록 스핀을하지 않고 tasks.put(task)을 사용해야한다고 생각합니다. offer()을 사용하여 작업을 실행할 작업 처리기를 결정하면 모든 작업 처리기의 대기열이 가득 찼을 때 주위를 돌고 있습니다.

자신의 작업 관리를 수행하는 경우 기본 제공 ExecutorService 클래스 중 하나를 대신 사용해보십시오. 그런 다음 모든 작업을 제출하거나 차단 큐를 사용하고 ExecutorService은 수영장에서의 작업을 각 스레드에게 먹이를 처리 할 수 ​​있습니다

// start 10 threads handling the tasks 
ExecutorService threadPool = Executors.newFixedThreadPool(10); 
// now submit tasks to the pools that will be run with the 10 threads 
threadPool.submit(task); 
... 

Runnable을 구현하기 위해 ComputerTask이있다 위의 예에서.

+0

감사합니다. 나는 그것을 들여다 볼 것이다. 한 가지 말하고 싶은 것은 대기열이 가득 채워지지 않을 것이며 그렇게 할 수있는 작업이 충분하지 않다는 것입니다. 그리고 그들이한다면 - 심각한 버그가 돌아 다니고 있습니다. – Robbietjuh