add: increase download concurrency. According to https://www.bilibili.com/video/av89055581.

This commit is contained in:
huanghongxun 2020-02-17 00:20:17 +08:00
parent cfd51915d3
commit a1226012ff
5 changed files with 36 additions and 20 deletions

View File

@ -23,9 +23,12 @@ import javafx.beans.value.ObservableObjectValue;
import org.jackhuang.hmcl.download.BMCLAPIDownloadProvider; import org.jackhuang.hmcl.download.BMCLAPIDownloadProvider;
import org.jackhuang.hmcl.download.DownloadProvider; import org.jackhuang.hmcl.download.DownloadProvider;
import org.jackhuang.hmcl.download.MojangDownloadProvider; import org.jackhuang.hmcl.download.MojangDownloadProvider;
import org.jackhuang.hmcl.task.Schedulers;
import org.jackhuang.hmcl.ui.FXUtils;
import java.util.Map; import java.util.Map;
import java.util.Optional; import java.util.Optional;
import java.util.concurrent.ThreadPoolExecutor;
import static org.jackhuang.hmcl.setting.ConfigHolder.config; import static org.jackhuang.hmcl.setting.ConfigHolder.config;
import static org.jackhuang.hmcl.util.Lang.mapOf; import static org.jackhuang.hmcl.util.Lang.mapOf;
@ -48,6 +51,10 @@ public final class DownloadProviders {
() -> Optional.ofNullable(providersById.get(config().getDownloadType())) () -> Optional.ofNullable(providersById.get(config().getDownloadType()))
.orElse(providersById.get(DEFAULT_PROVIDER_ID)), .orElse(providersById.get(DEFAULT_PROVIDER_ID)),
config().downloadTypeProperty()); config().downloadTypeProperty());
FXUtils.onChangeAndOperate(downloadProviderProperty, provider -> {
Schedulers.io().setMaximumPoolSize(provider.getConcurrency());
});
} }
public static DownloadProvider getDownloadProvider() { public static DownloadProvider getDownloadProvider() {

View File

@ -90,4 +90,8 @@ public class BMCLAPIDownloadProvider implements DownloadProvider {
.replace("https://authlib-injector.yushi.moe", apiRoot + "/mirrors/authlib-injector"); .replace("https://authlib-injector.yushi.moe", apiRoot + "/mirrors/authlib-injector");
} }
@Override
public int getConcurrency() {
return Math.max(Runtime.getRuntime().availableProcessors() * 2, 6);
}
} }

View File

@ -56,4 +56,10 @@ public interface DownloadProvider {
* @throws IllegalArgumentException if the version list does not exist * @throws IllegalArgumentException if the version list does not exist
*/ */
VersionList<?> getVersionListById(String id); VersionList<?> getVersionListById(String id);
/**
* The maximum download concurrency that this download provider supports.
* @return the maximum download concurrency.
*/
int getConcurrency();
} }

View File

@ -76,4 +76,9 @@ public class MojangDownloadProvider implements DownloadProvider {
public String injectURL(String baseURL) { public String injectURL(String baseURL) {
return baseURL; return baseURL;
} }
@Override
public int getConcurrency() {
return 6;
}
} }

View File

@ -22,16 +22,7 @@ import org.jackhuang.hmcl.util.Logging;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import javax.swing.*; import javax.swing.*;
import java.util.concurrent.CountDownLatch; import java.util.concurrent.*;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.concurrent.atomic.AtomicReference; import java.util.concurrent.atomic.AtomicReference;
/** /**
@ -43,9 +34,9 @@ public final class Schedulers {
private Schedulers() { private Schedulers() {
} }
private static volatile ExecutorService CACHED_EXECUTOR; private static volatile ThreadPoolExecutor CACHED_EXECUTOR;
public static synchronized Executor newThread() { public static synchronized ThreadPoolExecutor newThread() {
if (CACHED_EXECUTOR == null) if (CACHED_EXECUTOR == null)
CACHED_EXECUTOR = new ThreadPoolExecutor(0, Integer.MAX_VALUE, CACHED_EXECUTOR = new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60, TimeUnit.SECONDS, new SynchronousQueue<>(), Executors.defaultThreadFactory()); 60, TimeUnit.SECONDS, new SynchronousQueue<>(), Executors.defaultThreadFactory());
@ -53,22 +44,25 @@ public final class Schedulers {
return CACHED_EXECUTOR; return CACHED_EXECUTOR;
} }
private static volatile ExecutorService IO_EXECUTOR; private static volatile ThreadPoolExecutor IO_EXECUTOR;
public static synchronized Executor io() { public static synchronized ThreadPoolExecutor io() {
if (IO_EXECUTOR == null) if (IO_EXECUTOR == null)
IO_EXECUTOR = Executors.newFixedThreadPool(6, runnable -> { IO_EXECUTOR = new ThreadPoolExecutor(0, 6,
Thread thread = Executors.defaultThreadFactory().newThread(runnable); 60L, TimeUnit.SECONDS,
thread.setDaemon(true); new SynchronousQueue<>(),
return thread; runnable -> {
}); Thread thread = Executors.defaultThreadFactory().newThread(runnable);
thread.setDaemon(true);
return thread;
});
return IO_EXECUTOR; return IO_EXECUTOR;
} }
private static volatile ExecutorService SINGLE_EXECUTOR; private static volatile ExecutorService SINGLE_EXECUTOR;
public static synchronized Executor computation() { public static synchronized ExecutorService computation() {
if (SINGLE_EXECUTOR == null) if (SINGLE_EXECUTOR == null)
SINGLE_EXECUTOR = Executors.newSingleThreadExecutor(runnable -> { SINGLE_EXECUTOR = Executors.newSingleThreadExecutor(runnable -> {
Thread thread = Executors.defaultThreadFactory().newThread(runnable); Thread thread = Executors.defaultThreadFactory().newThread(runnable);