- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我从一个具有 main 方法的类启动多个线程,
public static void main(String[] args) {
for (int i = 0; i <= ALimit - 1; i++) {
MyThreadImplementsRunnable myThreadImplementsRunnable= new MyThreadImplementsRunnable();
Thread myThread= new Thread(myThreadImplementsRunnable);
myThread.start();
}
}
线程完成工作后,主线程仍在运行。如果我在 for 循环之后调用 System.exit(0),我的线程将无法完成其执行,事实上,它们甚至不会启动。有没有办法在所有线程完成执行后触发 System.exit(0),而不在每个线程上调用 join() 方法?感谢您的帮助。
最佳答案
有多种方法可以做到这一点。
<强>1。加入所有生成的线程。 (哦,对了,你不想要这个,跳到2)
这意味着保留对所有这些线程的引用:
public static void main(String[] args) throws InterruptedException {
Thread[] threads = new Thread[ALimit]; // array to keep track of our threads, or we could use a Collection
for (int i = 0; i < ALimit; i++) {
MyThreadImplementsRunnable myThreadImplementsRunnable= new MyThreadImplementsRunnable();
Thread myThread= new Thread(myThreadImplementsRunnable);
threads[i] = myThread; // remember it
myThread.start();
}
for (Thread thread : threads) {
thread.join(); // wait until the thread finishes, will return immediately if it's already finished.
}
System.exit(0); // all threads have finished, frankly it's a bit superfluous now.
}
<强>2。使用 CountDownLatch :
CountDownLatch 基本上是一个倒计时,线程可以等待倒计时达到 0。因此,如果每个完成倒计时的线程,主线程可以等待 0;
public static void main(String[] args) throws InterruptedException {
CountDownLatch finishedRunning = new CountDownLatch(ALimit); // Latch with ALimit countdowns needed to flip
for (int i = 0; i < ALimit; i++) {
MyThreadImplementsRunnable myThreadImplementsRunnable= new MyThreadImplementsRunnable();
Thread myThread= new Thread(() -> {
try {
myThreadImplementsRunnable.run();
} finally {
finishedRunning.countDown(); // one less to wait for, in a finally block, so exceptions don't mess up our count
}
};
myThread.start();
}
finishedRunning.await(); // waits until the count is 0
System.exit(0); // all threads have finished, frankly it's a bit superfluous now.
}
<强>3。使用 ExecutorService 并关闭:
ExecutorService
为您管理线程,您可以执行任务,然后只需等待 ExecutorService
终止即可;
public static void main(String[] args) throws InterruptedException {
ExecutorService executorService = Executors.newFixedThreadPool(ALimit);
for (int i = 0; i < ALimit; i++) {
MyThreadImplementsRunnable myThreadImplementsRunnable= new MyThreadImplementsRunnable();
executorService.execute(myThreadImplementsRunnable);
}
executorService.shutdown(); // will stop accepting new tasks, but all submitted tasks so far, will still be executed
boolean terminated = executorService.awaitTermination(3, TimeUnit.MINUTES); // we have to specify a timeout, returns a boolean which we can use to test whether it timed out or not, to maybe try and force termination
if (!terminated) {
// try and force things? Shut down anyway? log and wait some more?
}
System.exit(0); // all threads have finished, frankly it's a bit superfluous now.
}
<强>4。使用 ExecutorService 和 futures(这实际上就像再次加入所有线程,所以你可能想跳过这个):
ExecutorService
为您管理线程,您可以提交任务,跟踪返回的 Future
,然后只需等待每个 Future 的结果
到达;
public static void main(String[] args) throws InterruptedException {
Set<Future<?>> futures = new HashSet<>();
ExecutorService executorService = Executors.newFixedThreadPool(ALimit);
for (int i = 0; i < ALimit; i++) {
MyThreadImplementsRunnable myThreadImplementsRunnable= new MyThreadImplementsRunnable();
Future<?> future = executorService.submit(myThreadImplementsRunnable);
futures.add(future); // remember the future, pun intended ;)
}
executorService.shutdown(); // make sure the services terminates its threads when they're no longer needed.
for (Future<?> future : futures) {
try {
future.get();
} catch (ExecutionException e) {
// task failed with an exception : e.getCause() to see which
}
}
System.exit(0); // all threads have finished, frankly it's a bit superfluous now.
}
此方法的一种变体是将 ExecutorService
包装在 CompletionService
中,它将按完成的顺序返回 Future
:
public static void main(String[] args) throws InterruptedException {
ExecutorService executorService = Executors.newFixedThreadPool(ALimit);
CompletionService<Void> completionService = new ExecutorCompletionService<Void>(executorService);
for (int i = 0; i <= ALimit - 1; i++) {
MyThreadImplementsRunnable myThreadImplementsRunnable= new MyThreadImplementsRunnable();
completionService.submit(myThreadImplementsRunnable, null);
}
executorService.shutdown(); // make sure the services terminates its threads when they're no longer needed.
for (int i = 0; i < ALimit; i++) {
Future<?> future = completionService.take();
try {
future.get();
} catch (ExecutionException e) {
// task failed with an exception : e.getCause() to see which
}
}
System.exit(0); // all threads have finished, frankly it's a bit superfluous now.
}
<强>5。使用CompletableFutures
Java 8 为我们带来了 CompletableFuture
,它允许我们使用正在运行的任务作为构建 block 。我们可以简单地构建一个 CompletableFuture
来表示我们所有的异步任务。
public static void main(String[] args) throws InterruptedException {
CompletableFuture<?>[] completableFutures = new CompletableFuture<?>[ALimit];
for (int i = 0; i <ALimit; i++) {
MyThreadImplementsRunnable myThreadImplementsRunnable= new MyThreadImplementsRunnable();
completableFutures[i] = CompletableFuture.runAsync(myThreadImplementsRunnable);
}
CompletableFuture<Void> all = CompletableFuture.allOf(completableFutures);
try {
all.get(); // get the 'combined' result
} catch (ExecutionException e) {
// task failed with an exception : e.getCause() to see which
}
System.exit(0); // all threads have finished, frankly it's a bit superfluous now.
}
结论
CountDownLatch
可能就是您想要的,它很简单,而且开销很小。
ExecutorService
是专业人士会使用的,它清楚地分离了线程和任务的概念,提供了使用 Future
的选项,您可以取消它,并且可以使用它为各个任务提供异常处理。线程可以重复使用,并且可以独立于任务数量来定制线程数量。但所有这些可能都太过分了。
CompletionService
非常适合您需要在任务完成后立即处理任务的情况。
CompletableFuture
提供了 CountDownLatch
的简单性,但线程是为您管理的。
关于java - 线程完成后触发 System.exit(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45821312/
我相信所有这些(甚至是 die() 或 die(0))都是相同的。如果它们不相同,那么哪个更适合成功退出脚本?如果它们相同,是否有任何首选标准表明脚本成功完成?我倾向于使用 exit;. 编辑:所有答
我想知道Java中以下之间的区别 System.exit(0);System.exit(-1);System.exit(1); 我什么时候必须适本地使用上面的代码?
我注意到 Powershell 中有一个奇怪的行为。有两个 .ps1 文件: main.ps1: echo "running exit.ps1" $myexitcode = & ".\exit.p
Anylogic Process Modeling Library 中很少有像“Source”这样的 block 具有“On exit”和“On at exit”这样的操作。两者有什么区别? 我试图创
所以我有这个 Bash 脚本: #!/bin/bash PID=`ps -u ...` if [ "$PID" = "" ]; then echo $(date) Server off: no
(gdb) info symbol exit exit in section .text of /lib64/libc.so.6 (gdb) info symbol _exit _exit in se
如果我想启动一个简单的应用程序,几周前我使用它没有出现错误,我会收到错误消息。那是他的错误描述: Launching lib\main.dart on SM J530F in debug mode..
这个问题已经有答案了: Using Platform.exit() and System.exit(int) together (3 个回答) 已关闭 5 年前。 这里有人建议使用后者。我是java新
我的理解是,在 bash 中,一个普通的 exit 将完成一个具有最后一个命令的退出状态的脚本。但我也看到有人使用 exit $? 并且当我建议它具有相同的行为时被质疑。 这两个脚本之间有什么有意义的
我看到一些代码是这样做的: if(something){ echo 'exit from program'; die; } ...more code 和其他只使用 die 的人: if
exit和exit有什么区别!在 ruby 中? 最佳答案 一些事情: 退出处理程序以“退出”形式而非“退出!”形式运行。这意味着分配给“清理”的任何代码都不会使用“退出!”运行 “退出状态”在“退出
我们有一堆 .bat构建脚本由基于 PowerShell 的 GitLab 运行程序调用,这些脚本最近从以下内容重构: program args if !errorlevel! neq 0 exit
我想关闭具有指定返回码的 javafx 应用程序。浏览 SO 上的答案,我发现了以下成语: Platform.exit(); System.exit(0); 例如这里: Stop threads be
exit 和 C++ 中的 std::exit 有什么区别?我已经对其进行了研究,但我找不到任何东西。 这两个代码有什么区别: 1: if(SDL_Init(SDL_INIT_EVERYTHING)
我需要一个替代方法来在线程函数内终止 python 脚本。我的意图是在客户端输入 0 时终止服务器...这是否不起作用,因为线程尚未终止?这是我的代码: socket = socket.socket(
我想在崩溃后重新启动应用程序。我正在使用下面的代码来执行该任务。 Intent mStartActivity = new Intent(HomeActivity.this, SplashScreen
在Delphi中,你可以退出一个函数并给它一个返回值,这与C/C++/Java/C#等中的return关键字非常相似 Exit(1); 但是,我通常会写这样的内容: Result := 1; Exit
我想知道是否有任何方法可以处理浏览器退出事件。 例如,我想在用户单击交叉退出或关闭浏览器时发送查询。 最佳答案 我想我已经找到了解决办法。我没有在 IE 上测试过它,但它似乎在 Firefox 上运行
我在 Archlinux 的 mkinitcpio 脚本中找到了以下代码片段。 cleanup() { if [[ $workdir ]]; then # when PRESE
我使用以下代码计算数据帧所有行之间的余弦相似度: from pyspark.ml.feature import Normalizer from pyspark.mllib.linalg.distrib
我是一名优秀的程序员,十分优秀!