ars*_*nal 1 java multithreading synchronization
下面是其中的代码run method,我总是试图获得unique id from the availableExistingIds并releasing在通过使同一时刻它linked list order,但在某些情况下,我发现,我越来越NoSuchElementExceptionid是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
}
}
Run Code Online (Sandbox Code Playgroud)
问题陈述:-
我怎么能zero id case在我的代码中避免这种情况?我可以获得id = 0的一种情况是id池耗尽(空).当发生这种情况时,该行:
id = idPool.getExistingId();
Run Code Online (Sandbox Code Playgroud)
会失败的NoSuchElementException.在这种情况下,finally块将运行:
idPool.releaseExistingId(id);
Run Code Online (Sandbox Code Playgroud)
但是default value of 0自从第一行失败以来,id仍将拥有它.所以我最终"释放" 0并将其添加回id池,即使它从未在池中开始.然后,后来的任务可以合法地取0.这就是我不需要的东西.任何人都可以建议我如何在我的代码中克服这种情况?我总是希望id应该在范围内1 to 1000.
为什么不修改你的代码,以便在没有可用的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
}
}
Run Code Online (Sandbox Code Playgroud)
然后用这样的东西初始化池:
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);
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
146 次 |
| 最近记录: |