您好我正在尝试为二进制文件下载创建执行程序,我有大约100-200个文件要下载并存储在磁盘中。
这是我的DownloadExecutor.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()
,这个愿望是否可以省略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;
}
}
想象一下,每次按下按钮都会触发此代码。
答案 0 :(得分:0)
你的问题是
final BlockingQueue<Runnable> sPoolWorkQueue = new LinkedBlockingQueue<Runnable>(128);
如果所有执行程序线程都忙且队列已满,则抛出RejectedExecutionException。
增加池大小或使用无界队列。
顺便说一下。不要对你的单身人士使用双重检查锁定(https://wiki.sei.cmu.edu/confluence/display/java/LCK10-J.+Use+a+correct+form+of+the+double-checked+locking+idiom)。