【问题标题】:Performance Improvement for each thread using different unique id使用不同唯一 ID 的每个线程的性能改进
【发布时间】:2012-06-01 22:57:03
【问题描述】:

问题陈述是:-

每个线程使用 1 到 1000 之间的唯一 ID,并且程序必须运行 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); 
    }
}

【问题讨论】:

    标签: java multithreading threadpool executor


    【解决方案1】:

    我已经在上一个问题中向您解释过,您的代码向执行程序提交了数百万个任务,因为它在 60 分钟内循环提交任务,无需等待。

    目前还不清楚您的最终目标是什么,但实际上,您正在填充任务队列,直到您不再有任何可用内存。由于您没有解释程序的目标,因此很难为您提供任何解决方案。

    但是您可以做的第一件事是限制执行程序的任务队列的大小。这将强制主线程在每次队列满时阻塞。

    【讨论】:

    • 是的,我会将要运行的线程数设置为 CPU 上的确切内核数。
    • 我的最终目标是 - 程序必须运行一定分钟数并且每个线程必须在两个数字(1 和 1000 或者它可以是任意两个数字)之间使用不同的唯一 ID,并且需要将该唯一 id 传递给某个方法并使用该编号执行某些任务。以及如何限制我的执行者的任务队列的大小?
    • 这不是我所说的最终目标。这是一组任意约束,没有任何问题需要解决。鉴于这些限制,您可以启动 10 个线程,每个线程都有一个唯一的 ID,并循环写入 System.out 60 分钟。
    • 阅读ThreadPoolExecutor的javadoc,阅读《Java并发实战》一书。
    • 我已经阅读了 Executor 的 Java Doc 但不知道如何减少我的 executor 的任务队列的大小。是否有某种我们需要传入的参数?
    猜你喜欢
    • 2012-11-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-05
    • 1970-01-01
    • 2020-09-26
    • 1970-01-01
    • 2016-04-15
    相关资源
    最近更新 更多