Java 如何终止特定的阻塞线程

Java 如何终止特定的阻塞线程,java,multithreading,Java,Multithreading,场景:我有数量有限的独立任务,这些任务将分配给几个线程来完成这些任务。主线程应该等待所有线程完成它们的任务。虽然它在大部分时间都工作,但有时其中一个线程无法完成其任务,因此主线程会无限期地等待。怎么可能杀死那个被阻塞的线程 下面是解释该场景的示例代码 客户端类 public class ThreadStop { public static void main(String[] args){ List<Thread> threadList = getMyThreadList

场景:我有数量有限的独立任务,这些任务将分配给几个线程来完成这些任务。主线程应该等待所有线程完成它们的任务。虽然它在大部分时间都工作,但有时其中一个线程无法完成其任务,因此主线程会无限期地等待。怎么可能杀死那个被阻塞的线程

下面是解释该场景的示例代码

客户端类

public class ThreadStop {

public static void main(String[] args){

    List<Thread> threadList = getMyThreadList();        

    for (Thread thread : threadList) {
        thread.start();
    }

    System.out.println("Waiting for Child Threads to die");

    for (Thread thread : threadList) {
        try {
            thread.join();
            System.out.println(thread.getName() + " Finished its job");             
        } catch (InterruptedException e) {
            System.out.println("Interrupted Exception thrown by : "
                    + thread.getName());                
        }
    }

    System.out.println("All Child Threads Finished their Job");
}

private static List<Thread> getMyThreadList() {
    List<Thread> threadList = new ArrayList<>();
    MyThread myThread;
    Thread thread;
    for(int i=0; i<10; i++){
        myThread = new MyThread();
        thread = new Thread(myThread);
        thread.setName("Thread "+i);
        threadList.add(thread);
    }
    return threadList;
}
}  
public class MyThread implements Runnable{

@Override
public void run() {
    System.out.println("hello world by thread "+      Thread.currentThread().getName());        
}

}

注意请注意,我不能使用executor框架。

如果直接将任务显式编写为子类化
线程
,则无法使用executor框架[1]。在这种情况下,您应该使用带有超时值的
join()
。如果连接没有成功,您可以
中断()
线程(但这不是保证的“终止”)。直接戳线程并不是一种很好的做事方式——它就像一个你总是输的游戏,唯一的赢家是不玩

然而,如果任务编写得稍微理智一点/得益于现代的洞察力,它们至少可以包装成
可运行的
(或者实际上,它们是
可运行的
,只是传递给
线程
的构造函数)。此时您可以再次使用Executor框架

  • 尽管可以将线程实例直接传递给执行器,但前提是可以避免调用代码中其他地方的线程(因为如果其他代码也执行相同的任务,那么该任务在最佳情况下会执行两次)

  • 我不能使用executor框架:为什么?为什么任务永远都没有完成?是否在等待输入时被阻止?它是否卡在一个无限循环中?这很重要:如果它是一个bug,它应该被修复。如果它在等待时被阻塞,那么您应该能够中断它。向我们展示被阻止的任务在做什么。@JBNizet我不能使用executor framework,因为它是现有代码库的一部分,但没有使用该框架。如果我们不得不使用它,那将是大量的重构。被阻止的任务进行网络呼叫,有时似乎只是挂起。您的示例无法解释您的问题。。。因为线程在相当长的时间内不会阻塞。@turingcomplete中断线程与设置布尔值是一样的。不同之处在于,它还将通过抛出异常使大多数阻塞方法停止。我的观点是,使用一个单独的布尔值在大多数情况下是一个坏主意。这就是中断标志的作用。嗯,它至少需要以实际代码特有的方式进行阻塞。否则我们无法告诉你如何解决这个问题。线程实现可运行。您可以将线程传递给执行器。这不是设计代码的最佳方法,但它是正确的。@jbnize没有添加您的观察结果,请注意:如果其他代码“手动”调用线程上的
    start()
    run()
    ,它将无法正常工作,因为(最佳情况下)相同的任务会执行两次。如果
    t.interrupt()
    可以工作,那么为什么要从
    t.join(timeout)
    调用开始呢?为什么不立即中断所有线程?@jameslarge,因为你不想。您希望让线程运行,并希望在指定的最大超时值内完成工作。一旦您
    interrupt()
    成功了,这意味着线程所做的任何工作都可能是toast——它强制中断等待/通知锁等等。你只想在工作停止时终止它。