簡體   English   中英

每個線程使用唯一的ID並將其釋放以供重用

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM