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();
}
}
}
確實。謝謝:)我是個白癡。我會盡快接受你的回答。 – 2011-04-08 10:36:47