gpt4 book ai didi

java - 始终保持固定的线程数

转载 作者:太空宇宙 更新时间:2023-11-04 14:44:30 25 4
gpt4 key购买 nike

我正在从执行程序服务创建固定线程池。但是,如果出现一些运行时异常或错误(OutOfMemory Error),则线程将死亡,线程数量将不断减少,有时线程数量将为零,这称为静默线程终止。

一种方法是捕获 throwable(这不是一个好的做法)以避免线程被杀死。有什么办法可以让我们始终保持固定的线程数量。如果线程终止/死亡,则应自动生成一个新线程,以便我们始终拥有固定数量的线程。

任何建议都是值得赞赏的。

最佳答案

SingleThreadExecutor 的 ApiDocs声明如下:“但是请注意,如果该单个线程由于关闭之前执行期间的失败而终止,则如果需要执行后续任务,一个新线程将取代它。”

这似乎也适用于具有多个线程的线程池(请参见下面的演示程序)。因此,除非程序运行时遇到真正的 OutOfMemoryError(例如,不是分配了太大字节数组的意外错误),否则不会发生静默线程终止。如果程序遇到真正的 OutOfMemoryError ,那么我认为无能为力:必须执行的各种语句(在最终 block 中)可能会由于内存不足而突然无法执行,并且这可能会使程序处于不一致的状态(就像没有线程的线程池)。

下面的演示程序显示了所有任务都已执行,并且 thead-names 显示了线程池创建的新线程:

import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

public class SilentKillThread {

public static void main(String[] args) {

try {
new SilentKillThread().runTest();
} catch (Exception e) {
e.printStackTrace();
}
}

static int MAX_TASKS = 3;
static long SLEEP_TIME_MS = 400;

AtomicInteger tasksDoneCount = new AtomicInteger();

public void runTest() throws Exception {

ThreadPoolExecutor tp = new ThreadPoolExecutor(MAX_TASKS, MAX_TASKS,
60L, TimeUnit.SECONDS,
new LinkedBlockingQueue<Runnable>());

for (int i = 0; i < MAX_TASKS; i++) {
tp.execute(new FailingTask());
}
for (int i = 0; i < MAX_TASKS; i++) {
tp.execute(new SleepingTask());
}
tp.shutdown();
if (tp.awaitTermination(SLEEP_TIME_MS * 4, TimeUnit.MILLISECONDS)) {
System.out.println("Finished");
} else {
System.out.println("Finished but threadpool still active.");
}
System.out.println("Tasks done: " + tasksDoneCount.get());
}

class FailingTask implements Runnable {

@Override
public void run() {
String tname = Thread.currentThread().getName();
System.out.println(tname + " Sleeping");
try { Thread.sleep(SLEEP_TIME_MS); } catch (Exception e) { e.printStackTrace();}
int tcount = tasksDoneCount.incrementAndGet();
System.out.println(tname + " Done sleeping " + tcount);
throw new OutOfMemoryError();
}
}

class SleepingTask implements Runnable {

@Override
public void run() {
String tname = Thread.currentThread().getName();
System.out.println(tname + " Sleeping");
try { Thread.sleep(SLEEP_TIME_MS); } catch (Exception e) { e.printStackTrace();}
int tcount = tasksDoneCount.incrementAndGet();
System.out.println(tname + " Done sleeping " + tcount);
}
}
}

关于java - 始终保持固定的线程数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24583064/

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