0

問題の説明は次のとおりです。-

各スレッドは1から1000までの一意のIDを使用し、プログラムは60分以上実行する必要があるため、その60分ですべてのIDが終了する可能性があるため、それらのIDを再利用する必要があります。

私はそれを行ういくつかの方法を知っています、1つの方法は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); 
    }
}
4

1 に答える 1

4

前の質問で、コードが60分間ループでタスクを送信し、待機せずに何百万ものタスクをエグゼキュータに送信したことをすでに説明しました。

最終目標が何であるかは非常に明確ではありませんが、現状では、使用可能なメモリがなくなるまでタスクのキューを埋めています。あなたはあなたのプログラムの目的を説明していないので、あなたに解決策を与えるのは難しいです。

ただし、最初にできることは、エグゼキュータのタスクキューのサイズを制限することです。これにより、キューがいっぱいになるたびにメインスレッドが強制的にブロックされます。

于 2012-05-26T21:48:15.037 に答える