Java에서 Executor 서비스를 시험해보고 피보나치를 실행할 다음 코드를 작성했습니다 (예, 대용량의 재귀 버전 만 실행 프로그램 서비스를 강조합니다).Java Executor 서비스의 피보나치가 병렬보다 더 빠르게 순차적으로 실행됩니다.
놀랍게도 nThreads를 1로 설정하면 더 빨리 실행됩니다. 이는 Executor 서비스에 제출 된 각 "태스크"의 크기가 실제로 작음과 관련이 있습니다. 그러나 nThreads를 1로 설정 한 경우에도 여전히 동일한 숫자 여야합니다.
공유 된 Atomic 변수에 대한 액세스로 인해이 문제가 발생할 수 있는지 확인하려면 "텍스트 참조"라는 주석이있는 세 줄을 주석으로 처리하고 시스템 모니터를보고 실행이 얼마나 오래 걸리는 지 확인합니다. 그러나 결과는 같습니다.
왜 이런 일이 발생하는지 알고 싶습니다.
나는 BT와 비슷한 구현 방식과 비교하고 싶었다. F/J 구현보다 느린 것으로 나타났습니다.
public class MainSimpler {
static int N=35;
static AtomicInteger result = new AtomicInteger(0), pendingTasks = new AtomicInteger(1);
static ExecutorService executor;
public static void main(String[] args) {
int nThreads=2;
System.out.println("Number of threads = "+nThreads);
executor = Executors.newFixedThreadPool(nThreads);
Executable.inQueue = new AtomicInteger(nThreads);
long before = System.currentTimeMillis();
System.out.println("Fibonacci "+N+" is ... ");
executor.submit(new FibSimpler(N));
waitToFinish();
System.out.println(result.get());
long after = System.currentTimeMillis();
System.out.println("Duration: " + (after - before) + " milliseconds\n");
}
private static void waitToFinish() {
while (0 < pendingTasks.get()){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
executor.shutdown();
}
}
class FibSimpler implements Runnable {
int N;
FibSimpler (int n) { N=n; }
@Override
public void run() {
compute();
MainSimpler.pendingTasks.decrementAndGet(); // see text
}
void compute() {
int n = N;
if (n <= 1) {
MainSimpler.result.addAndGet(n); // see text
return;
}
MainSimpler.executor.submit(new FibSimpler(n-1));
MainSimpler.pendingTasks.incrementAndGet(); // see text
N = n-2;
compute(); // similar to the F/J counterpart
}
}
런타임 (약) :
- 1 실 : 11초
- 2 스레드 : 19초
- 4 개 스레드 : 19초
업데이트 : I 통지 집행 서비스 내에서 하나의 스레드를 사용하더라도 전체 프로그램은 내 컴퓨터의 4 개 코어를 모두 사용합니다 (각 코어는 평균 약 80 % 사용량). 이것은 Executor 서비스 내에서 더 많은 쓰레드를 사용하면 전체 프로세스가 느려지는 이유를 설명 할 수 있습니다.하지만 이제 Executor 서비스 내에서 단 하나의 쓰레드가 활성화되어 있다면이 프로그램은 4 코어를 사용합니까?
[관련 질문] [1]에서 말했듯이 가비지 수집과 관련이 있다고 생각합니다. 는 [1] : http://stackoverflow.com/questions/13645428/why-does-a-singlethreaded-executor-service-use-4-cores – Mahdi