Update guava, cleanup threading

This commit is contained in:
Manfred Karrer 2015-11-05 20:55:55 +01:00
parent 1a66d3cef5
commit def492a22a
21 changed files with 423 additions and 361 deletions

View file

@ -17,8 +17,9 @@
package io.bitsquare.common;
import com.google.common.util.concurrent.MoreExecutors;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
public class UserThread {
@ -30,7 +31,12 @@ public class UserThread {
UserThread.executor = executor;
}
public static Executor executor = Executors.newSingleThreadExecutor();
static {
// If not defined we use same thread as caller thread
executor = MoreExecutors.directExecutor();
}
private static Executor executor;
public static void execute(Runnable command) {
UserThread.executor.execute(command);

View file

@ -19,6 +19,9 @@ package io.bitsquare.common.util;
import com.google.common.base.Charsets;
import com.google.common.io.CharStreams;
import com.google.common.util.concurrent.ListeningExecutorService;
import com.google.common.util.concurrent.MoreExecutors;
import com.google.common.util.concurrent.ThreadFactoryBuilder;
import com.google.gson.*;
import javafx.scene.input.Clipboard;
import javafx.scene.input.ClipboardContent;
@ -32,6 +35,13 @@ import java.net.URI;
import java.net.URISyntaxException;
import java.net.URLConnection;
import java.net.URLEncoder;
import java.util.Random;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
/**
@ -51,6 +61,58 @@ public class Utilities {
return gson.toJson(object);
}
public static ListeningExecutorService getListeningExecutorService(String name,
int corePoolSize,
int maximumPoolSize,
long keepAliveTime) {
return MoreExecutors.listeningDecorator(getThreadPoolExecutor(name, corePoolSize, maximumPoolSize, keepAliveTime));
}
public static ThreadPoolExecutor getThreadPoolExecutor(String name,
int corePoolSize,
int maximumPoolSize,
long keepAliveTime) {
final ThreadFactory threadFactory = new ThreadFactoryBuilder()
.setNameFormat(name)
.setDaemon(true)
.build();
ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(corePoolSize, maximumPoolSize, keepAliveTime,
TimeUnit.SECONDS, new ArrayBlockingQueue<>(maximumPoolSize), threadFactory);
threadPoolExecutor.allowCoreThreadTimeOut(true);
threadPoolExecutor.setRejectedExecutionHandler((r, executor) -> log.warn("RejectedExecutionHandler called"));
return threadPoolExecutor;
}
public static Timer runTimerTaskWithRandomDelay(Runnable runnable, long minDelay, long maxDelay) {
return runTimerTaskWithRandomDelay(runnable, minDelay, maxDelay, TimeUnit.SECONDS);
}
public static Timer runTimerTaskWithRandomDelay(Runnable runnable, long minDelay, long maxDelay, TimeUnit timeUnit) {
return runTimerTask(runnable, new Random().nextInt((int) (maxDelay - minDelay)) + minDelay, timeUnit);
}
public static Timer runTimerTask(Runnable runnable, long delay) {
return runTimerTask(runnable, delay, TimeUnit.SECONDS);
}
public static Timer runTimerTask(Runnable runnable, long delay, TimeUnit timeUnit) {
Timer timer = new Timer();
timer.schedule(new TimerTask() {
@Override
public void run() {
Thread.currentThread().setName("TimerTask-" + new Random().nextInt(10000));
try {
runnable.run();
} catch (Throwable t) {
t.printStackTrace();
log.error("Executing timerTask failed. " + t.getMessage());
}
}
}, timeUnit.convert(delay, timeUnit));
return timer;
}
public static boolean isUnix() {
return isOSX() || isLinux() || getOSName().contains("freebsd");
}

View file

@ -44,6 +44,7 @@ import org.slf4j.LoggerFactory;
import java.io.*;
import java.nio.file.Paths;
import java.util.Random;
import java.util.concurrent.Callable;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
@ -67,7 +68,7 @@ public class FileManager<T> {
private final AtomicBoolean savePending;
private final long delay;
private final TimeUnit delayTimeUnit;
private final Callable<Void> saver;
private final Callable<Void> saveFileTask;
private T serializable;
@ -88,6 +89,7 @@ public class FileManager<T> {
executor = new ScheduledThreadPoolExecutor(1, builder.build());
executor.setKeepAliveTime(5, TimeUnit.SECONDS);
executor.allowCoreThreadTimeOut(true);
executor.setMaximumPoolSize(10);
executor.setExecuteExistingDelayedTasksAfterShutdownPolicy(false);
// File must only be accessed from the auto-save executor from now on, to avoid simultaneous access.
@ -95,7 +97,8 @@ public class FileManager<T> {
this.delay = delay;
this.delayTimeUnit = checkNotNull(delayTimeUnit);
saver = () -> {
saveFileTask = () -> {
Thread.currentThread().setName("Save-file-task-" + new Random().nextInt(10000));
// Runs in an auto save thread.
if (!savePending.getAndSet(false)) {
// Some other scheduled request already beat us to it.
@ -137,7 +140,7 @@ public class FileManager<T> {
if (savePending.getAndSet(true))
return; // Already pending.
executor.schedule(saver, delay, delayTimeUnit);
executor.schedule(saveFileTask, delay, delayTimeUnit);
}
public synchronized T read(File file) {