gpt4 book ai didi

java - 每个线程使用唯一 ID 并释放它以供重用

转载 作者:行者123 更新时间:2023-11-29 08:04:43 25 4
gpt4 key购买 nike

下面是在 run 方法 中的代码,我总是试图从 availableExistingIds 中获取 unique id 并在 releasing在同一时刻通过制作一个链表顺序,但在某些情况下我发现,我得到了NoSuchElementException并且id是零几次我认为任何时候都不应该这样。

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
}
}

问题陈述:-

如何在我的代码中避免这种零 id 情况?我可以获得 id = 0 的一种情况是 id 池耗尽(空)。当发生这种情况时,行:

id = idPool.getExistingId();

将失败并返回 NoSuchElementException。在这种情况下,finally block 将运行:

idPool.releaseExistingId(id);

但由于第一行失败,id 仍将具有其默认值 0。所以我最终“释放”0 并将它添加回 id 池,即使它从来没有在池中开始。然后后面的任务可以合法地取 0。而这正是我所不需要的。谁能建议我如何在我的代码中克服这种情况?我总是希望 id 应该在 1 到 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);

关于java - 每个线程使用唯一 ID 并释放它以供重用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12020878/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com