forked from j62/ctbrec
1
0
Fork 0

Use CompletableFuture.runAsync instead of creating new Threads

This commit is contained in:
0xb00bface 2020-12-27 15:38:33 +01:00
parent 0d2826ebf7
commit 53684668ab
21 changed files with 86 additions and 83 deletions

View File

@ -14,6 +14,7 @@ import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
@ -461,7 +462,7 @@ public class CamrecApplication extends Application {
}
private void checkForUpdates() {
Thread updateCheck = new Thread(() -> {
CompletableFuture.runAsync(() -> {
String url = "https://pastebin.com/raw/mUxtKzyB";
Request request = new Request.Builder().url(url).build();
try (Response response = httpClient.execute(request)) {
@ -488,9 +489,6 @@ public class CamrecApplication extends Application {
LOG.warn("Update check failed: {}", e.getMessage());
}
});
updateCheck.setName("Update Check");
updateCheck.setDaemon(true);
updateCheck.start();
}
public static Version getVersion() throws IOException {

View File

@ -1,6 +1,7 @@
package ctbrec.ui;
import java.util.Objects;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;
import org.slf4j.Logger;
@ -145,7 +146,7 @@ public class PreviewPopupHandler implements EventHandler<MouseEvent> {
}
private void createTimerThread() {
Thread timerThread = new Thread(() -> {
CompletableFuture.runAsync(() -> {
while(true) {
openCountdown--;
if(openCountdown == 0) {
@ -181,9 +182,5 @@ public class PreviewPopupHandler implements EventHandler<MouseEvent> {
}
}
});
timerThread.setDaemon(true);
timerThread.setPriority(Thread.MIN_PRIORITY);
timerThread.setName("PreviewPopupTimer");
timerThread.start();
}
}

View File

@ -4,6 +4,7 @@ import java.io.InputStream;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.function.Function;
@ -61,7 +62,7 @@ public class StreamSourceSelectionDialog {
}
});
selectStreamSource.setOnFailed(e -> onFail.apply(selectStreamSource.getException()));
new Thread(selectStreamSource).start();
CompletableFuture.runAsync(selectStreamSource);
}
private static class BestStreamSource extends StreamSource {

View File

@ -2,6 +2,7 @@ package ctbrec.ui;
import java.text.DecimalFormat;
import java.util.Objects;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import org.slf4j.Logger;
@ -78,7 +79,7 @@ public class TipDialog extends TextInputDialog {
}
}
};
new Thread(task).start();
CompletableFuture.runAsync(task);
}
private void showErrorDialog(Throwable throwable) {

View File

@ -3,6 +3,7 @@ package ctbrec.ui;
import java.text.DecimalFormat;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import org.slf4j.Logger;
@ -83,6 +84,6 @@ public class TokenLabel extends Label {
}
}
};
new Thread(task).start();
CompletableFuture.runAsync(task);
}
}

View File

@ -3,6 +3,7 @@ package ctbrec.ui.action;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -29,7 +30,7 @@ public class CheckModelAccountAction {
public void execute() {
String buttonText = b.getText();
b.setDisable(true);
Runnable checker = (() -> {
CompletableFuture.runAsync(() -> {
List<Model> deletedAccounts = new ArrayList<>();
try {
List<Model> models = recorder.getModels();
@ -66,6 +67,5 @@ public class CheckModelAccountAction {
});
}
});
new Thread(checker).start();
}
}

View File

@ -2,6 +2,7 @@ package ctbrec.ui.action;
import java.io.IOException;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -30,7 +31,7 @@ public class EditNotesAction {
public void execute() {
source.setCursor(Cursor.WAIT);
new Thread(() -> Platform.runLater(() -> {
CompletableFuture.runAsync(() -> Platform.runLater(() -> {
String notes = Config.getInstance().getSettings().modelNotes.getOrDefault(model.getUrl(), "");
Optional<String> newNotes = Dialogs.showTextInput(source.getScene(), "Model Notes", "Notes for " + model.getName(), notes);
newNotes.ifPresent(n -> {
@ -47,6 +48,6 @@ public class EditNotesAction {
});
table.refresh();
source.setCursor(Cursor.DEFAULT);
})).start();
}));
}
}

View File

@ -2,11 +2,7 @@ package ctbrec.ui.action;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.CompletableFuture;
import java.util.function.Consumer;
import ctbrec.Model;
@ -16,9 +12,6 @@ import javafx.scene.Node;
public class ModelMassEditAction {
static BlockingQueue<Runnable> queue = new LinkedBlockingQueue<>();
static ExecutorService threadPool = new ThreadPoolExecutor(2, 10, 10, TimeUnit.MINUTES, queue);
protected List<? extends Model> models;
protected Consumer<Model> action;
protected Node source;
@ -42,7 +35,7 @@ public class ModelMassEditAction {
Consumer<Model> cb = Objects.requireNonNull(callback, "Callback is null, call execute() instead");
source.setCursor(Cursor.WAIT);
for (Model model : models) {
threadPool.submit(() -> {
CompletableFuture.runAsync(() -> {
action.accept(model);
cb.accept(model);
Platform.runLater(() -> source.setCursor(Cursor.DEFAULT));

View File

@ -2,6 +2,7 @@ package ctbrec.ui.action;
import java.io.File;
import java.time.Instant;
import java.util.concurrent.CompletableFuture;
import ctbrec.Config;
import ctbrec.Model;
@ -25,7 +26,7 @@ public class OpenRecordingsDir {
File fileForRecording = Config.getInstance().getFileForRecording(selectedModel, ".mp4", Instant.now());
File dir = fileForRecording.getParentFile();
if (dir.exists()) {
new Thread(() -> DesktopIntegration.open(dir)).start();
CompletableFuture.runAsync(() -> DesktopIntegration.open(dir));
} else {
Dialogs.showError(source.getScene(), "Directory does not exist", "There are no recordings for this model", null);
}

View File

@ -1,5 +1,7 @@
package ctbrec.ui.action;
import java.util.concurrent.CompletableFuture;
import ctbrec.recorder.Recorder;
import ctbrec.ui.controls.Dialogs;
import javafx.application.Platform;
@ -20,7 +22,7 @@ public class ToggleRecordingAction {
public void execute() {
toggleButton.setCursor(Cursor.WAIT);
Thread t = new Thread(() -> {
CompletableFuture.runAsync(() -> {
try {
if (pause) {
recorder.pause();
@ -36,7 +38,5 @@ public class ToggleRecordingAction {
Platform.runLater(() -> toggleButton.setCursor(Cursor.DEFAULT));
}
});
t.setDaemon(true);
t.start();
}
}

View File

@ -34,6 +34,7 @@ package ctbrec.ui.controls;
import java.net.URL;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -167,7 +168,7 @@ public class SearchPopoverTreeList extends PopoverTreeList<Model> implements Pop
follow = new Button("Follow");
follow.setOnAction(evt -> {
setCursor(Cursor.WAIT);
new Thread(new Task<Boolean>() {
CompletableFuture.runAsync(new Task<Boolean>() {
@Override
protected Boolean call() throws Exception {
model.getSite().login();
@ -183,12 +184,12 @@ public class SearchPopoverTreeList extends PopoverTreeList<Model> implements Pop
}
Platform.runLater(() -> setCursor(Cursor.DEFAULT));
}
}).start();
});
});
record = new Button("Record");
record.setOnAction(evt -> {
setCursor(Cursor.WAIT);
new Thread(new Task<Void>() {
CompletableFuture.runAsync(new Task<Void>() {
@Override
protected Void call() throws Exception {
recorder.startRecording(model);
@ -199,7 +200,7 @@ public class SearchPopoverTreeList extends PopoverTreeList<Model> implements Pop
protected void done() {
Platform.runLater(() -> setCursor(Cursor.DEFAULT));
}
}).start();
});
});
getChildren().addAll(thumb, title, follow, record);

View File

@ -3,6 +3,7 @@ package ctbrec.ui.controls;
import java.io.InterruptedIOException;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
@ -157,14 +158,14 @@ public class StreamPreview extends StackPane {
running = false;
MediaPlayer old = videoPlayer;
Future<?> oldFuture = future;
new Thread(() -> {
CompletableFuture.runAsync(() -> {
if(oldFuture != null && !oldFuture.isDone()) {
oldFuture.cancel(true);
}
if(old != null) {
old.dispose();
}
}).start();
});
}
private void onError(MediaPlayer videoPlayer) {

View File

@ -1,5 +1,7 @@
package ctbrec.ui.controls;
import java.util.concurrent.CompletableFuture;
import javafx.animation.KeyFrame;
import javafx.animation.KeyValue;
import javafx.animation.Timeline;
@ -36,7 +38,7 @@ public final class Toast {
KeyFrame fadeInKey1 = new KeyFrame(Duration.millis(fadeInDelay), new KeyValue(toastStage.getScene().getRoot().opacityProperty(), 1));
fadeInTimeline.getKeyFrames().add(fadeInKey1);
fadeInTimeline.setOnFinished((ae) -> {
new Thread(() -> {
CompletableFuture.runAsync(() -> {
try {
Thread.sleep(toastDelay);
} catch (InterruptedException e) {
@ -47,7 +49,7 @@ public final class Toast {
fadeOutTimeline.getKeyFrames().add(fadeOutKey1);
fadeOutTimeline.setOnFinished((aeb) -> toastStage.close());
fadeOutTimeline.play();
}).start();
});
});
fadeInTimeline.play();
}

View File

@ -1,7 +1,16 @@
package ctbrec.ui.news;
import static ctbrec.io.HttpConstants.*;
import java.io.IOException;
import java.util.Objects;
import java.util.concurrent.CompletableFuture;
import org.json.JSONObject;
import com.squareup.moshi.JsonAdapter;
import com.squareup.moshi.Moshi;
import ctbrec.io.HttpException;
import ctbrec.ui.CamrecApplication;
import ctbrec.ui.controls.Dialogs;
@ -14,12 +23,6 @@ import javafx.scene.control.Tab;
import javafx.scene.layout.VBox;
import okhttp3.Request;
import okhttp3.Response;
import org.json.JSONObject;
import java.io.IOException;
import java.util.Objects;
import static ctbrec.io.HttpConstants.USER_AGENT;
public class NewsTab extends Tab implements TabSelectionListener {
private static final String ACCESS_TOKEN = "a2804d73a89951a22e0f8483a6fcec8943afd88b7ba17c459c095aa9e6f94fd0";
@ -36,7 +39,7 @@ public class NewsTab extends Tab implements TabSelectionListener {
@Override
public void selected() {
new Thread(this::loadToots).start();
CompletableFuture.runAsync(this::loadToots);
}
private void loadToots() {

View File

@ -1,17 +1,19 @@
package ctbrec.ui.sites.bonga;
import java.io.IOException;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.LinkedBlockingQueue;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import ctbrec.sites.bonga.BongaCams;
import ctbrec.sites.bonga.BongaCamsHttpClient;
import ctbrec.ui.controls.Dialogs;
import ctbrec.ui.sites.AbstractSiteUi;
import ctbrec.ui.sites.ConfigUI;
import ctbrec.ui.tabs.TabProvider;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
public class BongaCamsSiteUi extends AbstractSiteUi {
@ -44,7 +46,7 @@ public class BongaCamsSiteUi extends AbstractSiteUi {
} else {
BlockingQueue<Boolean> queue = new LinkedBlockingQueue<>();
try {
new Thread(() -> {
CompletableFuture.runAsync(() -> {
// login with external browser window
try {
new BongaCamsElectronLoginDialog(bongaCams.getHttpClient().getCookieJar());
@ -59,7 +61,7 @@ public class BongaCamsSiteUi extends AbstractSiteUi {
Thread.currentThread().interrupt();
LOG.error("Error while signaling termination", e);
}
}).start();
});
queue.take();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();

View File

@ -13,6 +13,7 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.CompletableFuture;
import org.json.JSONArray;
import org.json.JSONObject;
@ -136,7 +137,7 @@ public class CamsodaShowsTab extends Tab implements TabSelectionListener {
});
}
};
new Thread(task).start();
CompletableFuture.runAsync(task);
}
@Override
@ -202,7 +203,7 @@ public class CamsodaShowsTab extends Tab implements TabSelectionListener {
private void follow(Model model) {
setCursor(Cursor.WAIT);
new Thread(() -> {
CompletableFuture.runAsync(() -> {
try {
SiteUiFactory.getUi(model.getSite()).login();
model.follow();
@ -214,12 +215,12 @@ public class CamsodaShowsTab extends Tab implements TabSelectionListener {
setCursor(Cursor.DEFAULT);
});
}
}).start();
});
}
private void record(Model model) {
setCursor(Cursor.WAIT);
new Thread(() -> {
CompletableFuture.runAsync(() -> {
try {
recorder.startRecording(model);
} catch (InvalidKeyException | NoSuchAlgorithmException | IllegalStateException | IOException e) {
@ -229,11 +230,11 @@ public class CamsodaShowsTab extends Tab implements TabSelectionListener {
setCursor(Cursor.DEFAULT);
});
}
}).start();
});
}
private void loadImage(Model model, ImageView thumb) {
new Thread(() -> {
CompletableFuture.runAsync(() -> {
try {
String url = camsoda.getBaseUrl() + "/api/v1/user/" + model.getName();
Request detailRequest = new Request.Builder().url(url).build();
@ -270,7 +271,7 @@ public class CamsodaShowsTab extends Tab implements TabSelectionListener {
} catch (Exception e) {
LOG.error("Couldn't load model details", e);
}
}).start();
});
}
private Node createLabel(String string, boolean bold) {

View File

@ -2,6 +2,7 @@ package ctbrec.ui.sites.jasmin;
import java.io.IOException;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;
@ -55,7 +56,7 @@ public class LiveJasminSiteUi extends AbstractSiteUi {
lastLoginTime = System.currentTimeMillis();
BlockingQueue<Boolean> queue = new LinkedBlockingQueue<>();
new Thread (() -> {
CompletableFuture.runAsync(() -> {
// login with external browser window
try {
new LiveJasminElectronLoginDialog(liveJasmin.getHttpClient().getCookieJar());
@ -69,7 +70,7 @@ public class LiveJasminSiteUi extends AbstractSiteUi {
} catch (InterruptedException e) {
LOG.error("Error while signaling termination", e);
}
}).start();
});
try {
queue.take();

View File

@ -18,6 +18,7 @@ import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantLock;
@ -352,7 +353,7 @@ public class MyFreeCamsTableTab extends Tab implements TabSelectionListener {
if (Objects.equals(System.getenv("CTBREC_DEV"), "1")) {
MenuItem debug = new MenuItem("debug");
debug.setOnAction(e -> new Thread(() -> {
debug.setOnAction(e -> CompletableFuture.runAsync(() -> {
for (Model m : selectedModels) {
try {
List<StreamSource> sources = m.getStreamSources();
@ -364,7 +365,7 @@ public class MyFreeCamsTableTab extends Tab implements TabSelectionListener {
LOG.error("Couldn't get stream sources", e1);
}
}
}).start());
}));
menu.getItems().add(debug);
}

View File

@ -2,6 +2,7 @@ package ctbrec.ui.sites.showup;
import java.io.IOException;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.LinkedBlockingQueue;
import org.slf4j.Logger;
@ -46,7 +47,7 @@ public class ShowupSiteUi extends AbstractSiteUi {
} else {
BlockingQueue<Boolean> queue = new LinkedBlockingQueue<>();
try {
new Thread(() -> {
CompletableFuture.runAsync(() -> {
// login with external browser window
try {
new ShowupElectronLoginDialog(site.getHttpClient().getCookieJar());
@ -61,7 +62,7 @@ public class ShowupSiteUi extends AbstractSiteUi {
LOG.error("Error while signaling termination", e);
Thread.currentThread().interrupt();
}
}).start();
});
queue.take();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();

View File

@ -17,6 +17,7 @@ import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
@ -497,9 +498,9 @@ public class RecordingsTab extends Tab implements TabSelectionListener {
private void openContactSheet(JavaFxRecording recording) {
if (config.getSettings().localRecording) {
recording.getContactSheet().ifPresent(f -> new Thread(() -> DesktopIntegration.open(f)).start());
recording.getContactSheet().ifPresent(f -> CompletableFuture.runAsync(() -> DesktopIntegration.open(f)));
} else {
recording.getContactSheet().ifPresent(f -> new Thread(() -> {
recording.getContactSheet().ifPresent(f -> CompletableFuture.runAsync(() -> {
File target;
try {
target = File.createTempFile("cs_", ".jpg");
@ -517,7 +518,7 @@ public class RecordingsTab extends Tab implements TabSelectionListener {
} catch (IOException | InvalidKeyException | NoSuchAlgorithmException | IllegalStateException e) {
Dialogs.showError(getTabPane().getScene(), "Download Error", "An error occurred while downloading the contact sheet", e);
}
}).start());
}));
}
}
@ -527,7 +528,7 @@ public class RecordingsTab extends Tab implements TabSelectionListener {
Optional<String> newNote = Dialogs.showTextInput(source.getScene(), "Recording Notes", "", notes);
if (newNote.isPresent()) {
table.setCursor(Cursor.WAIT);
Thread backgroundThread = new Thread(() -> {
CompletableFuture.runAsync(() -> {
List<Exception> exceptions = new ArrayList<>();
try {
recording.setNote(newNote.get());
@ -543,13 +544,12 @@ public class RecordingsTab extends Tab implements TabSelectionListener {
});
}
});
backgroundThread.start();
}
}
private void pin(List<JavaFxRecording> recordings) {
table.setCursor(Cursor.WAIT);
Thread backgroundThread = new Thread(() -> {
CompletableFuture.runAsync(() -> {
List<Exception> exceptions = new ArrayList<>();
try {
for (JavaFxRecording javaFxRecording : recordings) {
@ -570,12 +570,11 @@ public class RecordingsTab extends Tab implements TabSelectionListener {
});
}
});
backgroundThread.start();
}
private void unpin(List<JavaFxRecording> recordings) {
table.setCursor(Cursor.WAIT);
Thread backgroundThread = new Thread(() -> {
CompletableFuture.runAsync(() -> {
List<Exception> exceptions = new ArrayList<>();
try {
for (JavaFxRecording javaFxRecording : recordings) {
@ -596,7 +595,6 @@ public class RecordingsTab extends Tab implements TabSelectionListener {
});
}
});
backgroundThread.start();
}
private void jumpToNextModel(KeyCode code) {
@ -647,11 +645,11 @@ public class RecordingsTab extends Tab implements TabSelectionListener {
private void onOpenDirectory(JavaFxRecording first) {
File tsFile = first.getAbsoluteFile();
new Thread(() -> DesktopIntegration.open(tsFile.getParent())).start();
CompletableFuture.runAsync(() -> DesktopIntegration.open(tsFile.getParent()));
}
private void triggerPostProcessing(List<JavaFxRecording> recs) {
new Thread(() -> {
CompletableFuture.runAsync(() -> {
for (JavaFxRecording rec : recs) {
try {
recorder.rerunPostProcessing(rec.getDelegate());
@ -660,7 +658,7 @@ public class RecordingsTab extends Tab implements TabSelectionListener {
LOG.error("Error while starting post-processing", e1);
}
}
}).start();
});
}
private void download(Recording recording) {
@ -796,7 +794,7 @@ public class RecordingsTab extends Tab implements TabSelectionListener {
}
private void deleteAsync(List<JavaFxRecording> recordings) {
Thread deleteThread = new Thread(() -> {
CompletableFuture.runAsync(() -> {
recordingsLock.lock();
try {
List<Recording> deleted = new ArrayList<>();
@ -822,7 +820,6 @@ public class RecordingsTab extends Tab implements TabSelectionListener {
Platform.runLater(() -> table.setCursor(Cursor.DEFAULT));
}
});
deleteThread.start();
}
public void saveState() {

View File

@ -484,7 +484,7 @@ public class ThumbCell extends StackPane {
void pauseResumeAction(boolean pause) {
setCursor(Cursor.WAIT);
new Thread(() -> {
CompletableFuture.runAsync(() -> {
try {
if (pause) {
recorder.suspendRecording(model);
@ -504,11 +504,11 @@ public class ThumbCell extends StackPane {
} finally {
Platform.runLater(() -> setCursor(Cursor.DEFAULT));
}
}).start();
});
}
private void startStopActionAsync(Model model, boolean start) {
new Thread(() -> {
CompletableFuture.runAsync(() -> {
try {
if (start) {
recorder.startRecording(model);
@ -523,7 +523,7 @@ public class ThumbCell extends StackPane {
} finally {
Platform.runLater(() -> setCursor(Cursor.DEFAULT));
}
}).start();
});
}
CompletableFuture<Boolean> follow(boolean follow) {