0
내 응용 프로그램 용 네트워크 스레드 관리자를 구현 중입니다. 나는 신속하게 요청하고 다음 두 가지 방법 호출하여 네트워크 스레드 지수를 발표 JUnit 테스트, 만든 : 스레드가 작업을 완료 한 후Java 동기화 도움말 요청
protected static final List <Integer> currThreads = new ArrayList <Integer>();
protected static int maxThreads = 5;
protected static int lastGrantedId = 0;
public static synchronized int reqNewThread(){
if (currThreads.size() >= maxThreads) return -1;
++lastGrantedId;
currThreads.add(lastGrantedId);
return lastGrantedId;
}
public static void threadFinished(final int threadId) throws InternalError{
if (threadId == -1) return;
synchronized (currThreads) {
boolean works = currThreads.remove(Integer.valueOf(threadId));
assert works : ("threadId: " + threadId);
}
}
을 currThreads
가 비어 있지 않습니다 만, reqNewThread
및 threadFinished
같은 호출 수를 가지고 remove()
은 항상 true
입니다. 전체 threadFinished
메서드를 동기화하면 올바르게 작동합니다. 질문은 - 왜? 유일하게 사용 된 전역 변수는 이미 동기화 되었습니까? 아닙니다.
JUnit4 테스트 코드 :
final int iters = 15;
final Runnable getAndFree = new GetAndFree(iters);
final int sz = 15;
final Thread[] t = new Thread[sz];
for (int i = 0; i < sz; i++)
t[i] = new Thread(getAndFree);
for (int i = 0; i < sz; i++)
t[i].start();
for (int i = 0; i < sz; i++)
t[i].join();
assertEquals(0, currThreads.size());
테스터 스레드 소스 :
private class GetAndFree implements Runnable {
int iters;
public GetAndFree(int iters){
this.iters = iters;
}
@Override
public void run(){
try {
int id = -1;
for (int i = 0; i < iters; i++) {
while ((id = reqNewThread()) == -1) {
Thread.sleep(25);
};
System.out.println("Strarted: " + id);
Thread.sleep((long)(Math.random() * 10));
threadFinished(id);
System.out.println("Finished: " + id);
} // for
} catch(final Exception ex) {
ex.printStackTrace();
}
}
}
실제로. 고마워. :) 나는 바보 야. 가능한 빨리 답변 해 드리겠습니다. –