qrt*_*tt1 6 java multithreading executorservice
我使用ExecutorService在不同的线程中运行许多任务.有时,在线程池中等待的Runnable实例太多可能会导致Out of Memory问题.
我尝试编写一个阻塞作业执行器来解决它.这有什么官方解决方案吗?
例如:
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();
Run Code Online (Sandbox Code Playgroud)
这是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);
}
}
}
Run Code Online (Sandbox Code Playgroud)
小智 12
有两种方法可以实现.排队等待运行的runnables太多,或者同时运行的线程太多.如果有太多的作业排队,你可以使用一个固定大小BlockingQueue的ExecutorService限制,可排队的项目数.然后,当您尝试对新任务进行排队时,操作将阻塞,直到队列中有空间为止.
如果一次运行的线程太多,您可以通过调用Executors.newFixedThreadPool所需的线程数来限制可用于在ExecutorService中运行任务的线程数.
| 归档时间: |
|
| 查看次数: |
6246 次 |
| 最近记录: |