[英]Each Thread using unique ID and releasing it for reuse
下面是在run method
的代碼,我一直試圖unique id from the availableExistingIds
獲取unique id from the availableExistingIds
並通過建立linked list order
同時releasing
它,但是在某些情況下,我發現我得到了NoSuchElementException
和id是zero few times
,我認為任何時候都不應該是這種情況。
class IdPool {
private final LinkedList<Integer> availableExistingIds = new LinkedList<Integer>();
public IdPool() {
for (int i = 1; i <= 1000; i++) {
availableExistingIds.add(i);
}
}
public synchronized Integer getExistingId() {
return availableExistingIds.removeFirst();
}
public synchronized void releaseExistingId(Integer id) {
availableExistingIds.add(id);
}
}
class ThreadNewTask implements Runnable {
private IdPool idPool;
private int id;
public ThreadNewTask(IdPool idPool) {
this.idPool = idPool;
}
public void run() {
try {
id = idPool.getExistingId();
//Anything wrong here?
if(id==0) {
System.out.println("Found Zero");
}
someMethod(id);
} catch (Exception e) {
System.out.println(e);
} finally {
idPool.releaseExistingId(id);
}
}
// This method needs to be synchronized or not?
private synchronized void someMethod(Integer id) {
System.out.println("Task: " +id);
// and do other calcuations whatever you need to do in your program
}
}
問題陳述:-
如何在我的代碼中避免這種zero id case
? 我可以讓id = 0的一種情況是id池耗盡(空)。 發生這種情況時,該行將:
id = idPool.getExistingId();
將失敗,並顯示NoSuchElementException
。 在這種情況下,finally塊將運行:
idPool.releaseExistingId(id);
但是default value of 0
由於第一行失敗,所以id的default value of 0
仍為default value of 0
。 所以我最終“釋放” 0
並將其添加回id池中,即使它根本不在池中。 然后,后面的任務可以合法地取0。 這就是我不需要的。 誰能在我的代碼中建議我如何克服這種情況? 我一直希望id應該在1 to 1000
的范圍內。
您為什么不修改代碼,以便在沒有可用ID的情況下不會崩潰,而是等待一個可用的ID?
否則,每次您有太多線程同時工作時,池將被耗盡,並且您將不得不處理很多失敗的線程。 同步工作也會自動為您完成。
編輯:這是修改后的代碼
class ThreadNewTask implements Runnable {
private BlockingQueue<Integer> pool;
private int id;
public ThreadNewTask(BlockingQueue<Integer> pool) {
this.pool = pool;
}
public void run() {
try {
id = pool.take();
someMethod(id);
} catch (Exception e) {
System.out.println(e);
} finally {
pool.offer(id);
}
}
private void someMethod(Integer id) {
System.out.println("Task: " +id);
// and do other calcuations whatever you need to do in your program
}
}
然后,您使用以下內容初始化池:
LinkedList<Integer> availableExistingIds = new LinkedList<Integer>();
for (int i = 1; i <= 1000; i++) {
availableExistingIds.add(i);
}
BlockingQueue<Integer> pool = new ArrayBlockingQueue<Integer>(1000, false, availableExistingIds);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.