Kylar의 대답은 올바른 것입니다. Java 클래스 라이브러리에서 제공하는 executor 클래스를 사용하면 처음부터 스레드 풀링을 구현하는 것이 아닙니다.
그러나 나는 당신의 질문에서 코드를 토론하는 것이 유용 할 수 있으며, 왜 효과가 없는지 생각했습니다. (내가 할 수있는 한 최선을 다한 부분을 채웠습니다 ...)
public class MyThread extends Thread {
private static int counter;
public MyThread(String fileName, Object lock) {
// Save parameters in instance variables
}
public void run() {
// Do stuff with instance variables
counter--;
}
public static void main(String[] args) {
// ...
for (final File filename : folder.listFiles()) {
Object lock1 = new Object();
new MyThread(filename, lock1).start();
counter++;
while (counter > 5);
}
// ...
}
}
그래, 뭐가 잘못 되었니? 왜 작동하지 않습니까?
첫 번째 문제는 main
에서 동기화를 수행하지 않고 counter
을 읽고 쓰고 있다는 것입니다. 나는 작업자 스레드에 의해 업데이트되고 있다고 가정한다. 코드는 그렇지 않다. 즉, 메인 쓰레드가 자식 쓰레드의 업데이트 결과를 보지 못하게 될 가능성이 있습니다. 즉, while (counter > 5);
은 무한 루프 일 수 있습니다. (사실,이 꽤 가능성이있다. JIT 컴파일러는 counter > 5
단순히 이전 counter++;
문 뒤에 레지스터에 남아 counter
의 값을 테스트하는 코드를 생성 할 수있다.
두 번째 문제는 당신 while (counter > 5);
루프가 있다는 것이다 믿을 수 없을만큼 많은 자원이 낭비되고 있습니다 .JVM에 변수를 폴링하라는 메시지가 표시됩니다. 그러면 1 초당 1 억 배의 처리량이 발생할 것입니다. 하나의 프로세서 (코어)를 실행해야합니다. 저급 프리미티브를 사용하여 이러한 종류의 작업을 구현하려면 자바의 Object.wait()
및 Object.notify()
메서드를 사용해야합니다 (예 : 메인 스레드가 대기하고 각 작업자 스레드가 알립니다)
+1. 바퀴를 재발 명하는 감각이 없습니다. 그래도 ThreadPoolExecutor라고 생각합니다. 내가 아는 J2SE에는 ExecutorPool이 없다. –
Jdk5 이후 스레드 처리를위한 많은 inbuit 클래스가 있습니다.kylar가 제안한 것처럼 Executorpool을 사용하는 것이 더 좋습니다 – kosa
그래, 실제로 ExecutorService를 의미했습니다. 당신에게 요지를 제공하기 위해 고정 및 추가 슈퍼 거친 소스 코드. – Kylar