我有多个类型的多个线程(不同的类)。我希望万一他们中的一个抛出异常并死于被另一个新线程替换。我知道连接线程函数但是我将如何为5种不同类型的线程实现它们,例如在类型1线程模具被立即替换而不必等待类型2首先死亡的情况下。
这是一些示例伪代码。
class1 implements runnable{
void run(){
try{
while(true){
repeat task
}
} catch(Exception e){
log error
}
}
}
class2 implements runnable{
void run(){
try{
while(true){
repeat task
}
} catch(Exception e){
log error
}
}
}
class3 implements runnable{
void run(){
try{
while(true){
repeat task
}
} catch(Exception e){
log error
}
}
}
public main(){
// start all threads .start()
}
答案 0 :(得分:3)
我希望万一其中一个抛出一个异常并死掉另一个新线程。
我不太明白为什么你不能这样做:
public void run() {
// only quit the loop if the thread is interrupted
while (!Thread.currentThread().isInterrupted()) {
try {
// do some stuff that might throw
repeat task;
} catch (Exception e) {
// recover from the throw here but then continue running
}
}
}
为什么需要重新启动新线程?仅仅因为任务抛出异常并不意味着它在某种程度上是腐败的,它需要一个新的才能正常工作。如果您尝试捕获所有例外(包括RuntimeException
),则catch (Exception e)
会执行此操作。如果你想非常小心,你甚至可以抓住Throwable
,以防有Error
被生成 - 这是相对罕见的。
如果您实际上有多个任务(或者实际上在任何时候处理线程),您应该考虑使用ExecutorService
类。请参阅Java tutorial。
// create a thread pool with 10 workers
ExecutorService threadPool = Executors.newFixedThreadPool(10);
// or you can create an open-ended thread pool
// ExecutorService threadPool = Executors.newCachedThreadPool();
// define your jobs somehow
threadPool.submit(new Class1());
threadPool.submit(new Class2());
...
// once we have submitted all jobs to the thread pool, it should be shutdown
threadPool.shutdown();
因此,不是让一个线程执行多个任务,而是启动一个线程池,它会根据需要启动线程来完成一堆任务。如果任务失败,您可以确定向池中提交另一个任务,尽管这有点奇怪。
如果您想等待所有任务完成,请使用:
threadPool.awaitTermination(Long.MAX_VALUE, TimeUnit.MILLISECONDS);
答案 1 :(得分:1)
boolean shouldStop() { // it's a good idea to think about how/when to stop ;) return false; } void runThreadGivenType(final Runnable taskToRun) { new Thread() { @Override public void run() { try { taskToRun.run(); } finally { if (!shouldStop()) { runThreadGivenType(taskToRun); } } } }.start(); } public void main(String[] args) throws Exception { runThreadGivenType(new Runnable() { public void run() { System.out.println("I'm almost immortal thread!"); throw new RuntimeException(); } }); TimeUnit.SECONDS.sleep(10); }
并且考虑执行程序来管理线程池也是一个好主意。普通的,[un / hand]管理的线程不是最好的做法;)