gpt4 book ai didi

java - 一个线程如何等到另一个线程完成才能触发某些操作

转载 作者:行者123 更新时间:2023-11-29 05:12:49 24 4
gpt4 key购买 nike

如下代码所示,我在工作线程 fileThread 上加载了一个大文件,当该线程加载文件时,我创建了另一个线程 fileLoadIndicator 来在屏幕上显示类似忙碌指示符的内容。我现在要做的是:在 fileLoadIndicator 线程完成后,我想启用一个按钮,但只能在 fileLoadIndicator 线程完成后。

我的尝试:

loadFile();// the very heavy file
/**
* The below thread "fileLoadIndicator"is to show busy indicator while our main file
that takes approx. 8 seconds to be loaded
*
*/
fileLoadIndicator = new Thread(fileLoadIndicatorRun);
fileLoadIndicator.start();

indicatorMonitor = new Thread(indicatorMonitorRun);
indicatorMonitor.start();
...
...
Runnable fileLoadIndicatorRun = new Runnable() {

@Override
public void run() {
// TODO Auto-generated method stub
statusarea.append(Log.w(TAG, "busyIndicatorRunnable", "Loading."));
StringBuilder sb = new StringBuilder(".");
do {
try {
fileThread.join(1500);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
sb.append(".");
statusarea.append(sb.toString());
} while (fileThread.getState() != State.TERMINATED);
//statusarea.append("/n");
}
};

Runnable indicatorMonitorRun = new Runnable() {

@Override
public void run() {
// TODO Auto-generated method stub
try {
fileLoadIndicator.join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
setViewEnableState(Bpause, true);
}
};

但是 indicatorMonitorRun 中发生的事情是,indicatorMonitor 线程等待整个方法 loadFile(),它处理重文件行按行,整个过程可能需要 70 分钟,完成。我只想启用一个按钮,只有当 fileLoadIndicator 线程完成时,我不应该等到整个文件加载和处理很长时间。

请告诉我该怎么做。

最佳答案

我建议使用 ExecutorService 来管理您的线程池,如果您使用的是 Java 8,请利用 CompletableFuture,因为它简化了这些类型的任务,而不需要复杂的线程等待/通知和 java.util.concurrency 类型,例如:

package so.thread.wait;

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

public class LongThreadWait {

public static void main(String[] args) throws Exception {

// thread pool for long running loaders
final ExecutorService fileLoaders = Executors.newCachedThreadPool();

// hook to be invoked when the file is done loading
final CompletableFuture<Long> completionFuture = new CompletableFuture<>();
completionFuture.thenAcceptAsync(LongThreadWait::completionConsumer);

fileLoaders.submit(new FileLoader(completionFuture));

Thread.sleep(TimeUnit.SECONDS.toMillis(3));
}

private static void completionConsumer(Long millis) {
System.out.println("Completed on Thread [" + Thread.currentThread().getName() + "] in " + millis + " ms");
}

private static class FileLoader implements Runnable {
private CompletableFuture<Long> completionFuture;

public FileLoader(CompletableFuture<Long> completionFuture) {
this.completionFuture = completionFuture;
}

@Override
public void run() {
long start = System.currentTimeMillis();
// load file for a long time
System.out.println("Loading file on Thread [" + Thread.currentThread().getName() + "]");

try {
Thread.sleep(TimeUnit.SECONDS.toMillis(2));
} catch (InterruptedException e) {
e.printStackTrace();
}
long end = System.currentTimeMillis();
// invoke the completion future with the elapsed milliseconds
completionFuture.complete(end - start);
}
}

}

CompletableFuture.thenAcceptAsync(..) 默认在 JVM 的默认“ForkJoin”线程池中运行提供的钩子(Hook),还有一个可选的第二个参数,您可以在其中提供自己的 ExecutorService 来定义完成钩子(Hook)是哪个线程执行于。

这种类型的设置简化了线程管理和复杂的等待语义。

您还应注意,CompletableFuture 具有全面流畅的 API,可简化线程结果的复杂链接。

关于java - 一个线程如何等到另一个线程完成才能触发某些操作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27744163/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com