Singleton executor Java



嗨,我正在尝试为二进制文件下载创建执行器,我有大约 100-200 个文件要下载并存储在磁盘中。

这是我的下载执行器.java

public final class DownloadExecutor {
private static DownloadExecutor executor;
private ExecutorService executorService;
private static final ThreadFactory sThreadFactory = new ThreadFactory() {
private final AtomicInteger mCount = new AtomicInteger(1);
public Thread newThread(Runnable r) {
return new Thread(r, "DownloadExecutor #" + mCount.getAndIncrement());
}
};
public static DownloadExecutor getInstance() {
if (executor == null) {
synchronized (DownloadExecutor.class) {
executor = new DownloadExecutor();
}
}
return executor;
}
private DownloadExecutor() {
final BlockingQueue<Runnable> sPoolWorkQueue =
new LinkedBlockingQueue<Runnable>(128);
final int CPU_COUNT = Runtime.getRuntime().availableProcessors();
// We want at least 2 threads and at most 4 threads in the core pool,
// preferring to have 1 less than the CPU count to avoid saturating
// the CPU with background work
final int CORE_POOL_SIZE = Math.max(2, Math.min(CPU_COUNT - 1, 4));
final int MAXIMUM_POOL_SIZE = CPU_COUNT * 2 + 1;
final int KEEP_ALIVE_SECONDS = 2;
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append("CPU: " + CPU_COUNT);
stringBuilder.append(",CORE POOL: " + CORE_POOL_SIZE);
stringBuilder.append(",MAX POOL: " + MAXIMUM_POOL_SIZE);
System.out.println("Executor log: " + stringBuilder.toString());
ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(
CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, KEEP_ALIVE_SECONDS, TimeUnit.SECONDS,
sPoolWorkQueue, sThreadFactory);
threadPoolExecutor.allowCoreThreadTimeOut(true);
executorService = threadPoolExecutor;
}
public void execute(Callable<?> callable) {
System.out.println("Adding");
executorService.submit(callable);
}
}

我使用以下代码提交任务DownloadExecutor.getInstance().execute(someCallable);

最初当我触发这一切时,所有下载都会成功,但是当我下次触发时它会抛出java.util.concurrent.RejectedExecutionException.

请注意,我不想对此使用shutDown(),是否可以省略关闭。我开始知道当您尝试提交终止服务的任务时java.util.concurrent.RejectedExecutionException发生。

呼叫代码

for (int i = 0; i < totalVideos; i++) {
try {
DownloadExecutor.getInstance().execute(new YoutubeFilewriter(downloadRepository,
videoDao, listResource.data.get(i), parentPath, YoutubeVideoDownloader.this));
} catch (IOException e) {
e.printStackTrace();
++failedVideos;
}
}

想象一下,每次单击按钮都会触发此代码。

你的问题是

final BlockingQueue<Runnable> sPoolWorkQueue = new LinkedBlockingQueue<Runnable>(128);

如果所有执行程序线程都繁忙并且队列已满,则会抛出拒绝执行异常。

增加池大小或使用无限队列。

顺便说一句,不要对单例 (https://wiki.sei.cmu.edu/confluence/display/java/LCK10-J.+Use+a+correct+form+of+the+double-checked+locking+idiom( 使用双重检查锁定。

最新更新