ExecutorServiceを使用して、さまざまなスレッドで多くのタスクを実行します。 スレッドプール内で待機中のRunnableインスタンスが多すぎると、Out of Memoryの問題が発生することがあります。ExecutorServiceのスレッドをどのように制限しますか?
私はそれを解決するためにブロックジョブエグゼキュータを書きます。それを行うための公式な解決策はありますか?例えば
:ここ
BlockingJobExecutor executor = new BlockingJobExecutor(3);
for (int i = 0; i < 1000; i++) {
executor.addJob(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
LogFactory.getLog(BTest.class).info("test " + System.currentTimeMillis());
}
});
}
executor.shutdown();
はBlockingJobExecutorクラスです:
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
public class BlockingJobExecutor {
AtomicInteger counter = new AtomicInteger();
ExecutorService service;
int threads;
public BlockingJobExecutor(int threads) {
if (threads < 1) {
throw new IllegalArgumentException("threads must be greater than 1.");
}
service = Executors.newFixedThreadPool(threads);
this.threads = threads;
}
static class JobWrapper implements Runnable {
BlockingJobExecutor executor;
Runnable job;
public JobWrapper(BlockingJobExecutor executor, Runnable job) throws InterruptedException {
synchronized (executor.counter) {
while (executor.counter.get() >= executor.limit()) {
executor.counter.wait();
}
}
this.executor = executor;
this.job = job;
}
@Override
public void run() {
try {
job.run();
} finally {
synchronized (executor.counter) {
executor.counter.decrementAndGet();
executor.counter.notifyAll();
}
}
}
}
public int limit() {
return threads;
}
public void shutdown() {
service.shutdown();
try {
service.awaitTermination(Long.MAX_VALUE, TimeUnit.MILLISECONDS);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
public void addJob(Runnable job) {
try {
service.execute(new JobWrapper(this, job));
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
実行待ちのジョブが多すぎるか、あまりにも多くのスレッドが同時に実行されていることを意味しますか? – chrylis
実行待ちジョブが多すぎます。 – qrtt1