问题陈述是:
每个线程使用的唯一ID在1到1000之间,程序必须运行60分钟或更长时间,因此在60分钟内,所有ID都有可能完成,所以我需要再次使用这些ID,
我知道几种方法,其中一种是我从StackOverflow寻求帮助时编写的,但是当我尝试运行此代码时,我发现,运行几分钟后,该程序变得非常慢,并且需要花费很多时间。是时候在控制台上打印ID。而且有时我还会收到OutOfMemory错误。有没有更好的方法来解决此类问题?
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;
public ThreadNewTask(IdPool idPool) {
this.idPool = idPool;
}
public void run() {
Integer id = idPool.getExistingId();
someMethod(id);
idPool.releaseExistingId(id);
}
private void someMethod(Integer id) {
System.out.println("Task: " +id);
}
}
public class TestingPool {
public static void main(String[] args) throws InterruptedException {
int size = 10;
int durationOfRun = 60;
IdPool idPool = new IdPool();
// create thread pool with given size
// create thread pool with given size
ExecutorService service = new ThreadPoolExecutor(size, size, 500L, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(10), new ThreadPoolExecutor.CallerRunsPolicy());
// queue some tasks
long startTime = System.currentTimeMillis();
long endTime = startTime + (durationOfRun * 60 * 1000L);
// Running it for 60 minutes
while(System.currentTimeMillis() <= endTime) {
service.submit(new ThreadNewTask(idPool));
}
// wait for termination
service.shutdown();
service.awaitTermination(Long.MAX_VALUE, TimeUnit.DAYS);
}
}
最佳答案
我已经在上一个问题中向您解释过,您的代码向执行程序提交了数百万个任务,因为它在60分钟内循环提交任务,而没有等待。
最终目标是什么还不清楚,但实际上,您正在填充任务队列,直到没有可用的内存为止。由于您没有解释程序的目标,因此很难为您提供任何解决方案。
但是您可以做的第一件事是限制执行程序的任务队列的大小。这将在每次队列满时强制主线程阻塞。
关于java - 使用不同的唯一ID改善每个线程的性能,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/10770003/