run method
以下は、 で、常に取得しようとしunique id from the availableExistingIds
ているコードであり、releasing
を作成することによって同時に取得しようとしていますlinked list order
が、特定のケースでは、取得していて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 を取得できるシナリオの 1 つは、id プールが使い果たされた (空になった) 場合です。その場合、次の行:
id = idPool.getExistingId();
で失敗しNoSuchElementException
ます。この場合、finally ブロックが実行されます。
idPool.releaseExistingId(id);
default value of 0
ただし、最初の行が失敗したため、id はまだ保持されます。0
したがって、最初はプールになかったにもかかわらず、「解放」してIDプールに追加し直すことになります。その後、後のタスクは合法的に 0 を取ることができます。そして、それは私が必要としないものです。私のコードでこのシナリオを克服する方法を誰かに提案できますか? 私は常に id が の範囲内にあることを望んでいます1 to 1000
。