【问题标题】:Is there a 100% sure way to stop a thread after all other threads finish their jobs in Java?在所有其他线程在 Java 中完成工作后,是否有 100% 确定的方法来停止线程?
【发布时间】:2023-04-09 23:57:01
【问题描述】:

我有一个消费者线程和几个生产者线程共享一个工作列表。生产者线程在达到其“生产限制”时结束。但是,如果不使用“中断”,我就无法成功结束消费者线程。

我正在尝试停止消费者线程。在消费者线程中,我使用了 AtomicBoolean 变量(JDK 1.6)来停止 run 方法内的循环。但是,我无法在主类中找到一种方法来了解所有生产者线程都已结束。尝试在主类的生产者线程上使用连接。

请注意,所有线程都同时运行。我的主类中的当前代码在没有完成所有工作的情况下突然结束了消费者线程。我正在寻找答案而不使用

ExecutorService/Future/Callable.

按照我的主要方法中的代码 sn-p:

//Job container
JobContainer<CalcJob> jobContainer = new JobContainer<CalcJob>(100);

//One Consumer
Consumer consumer = new Consumer(jobContainer);
Thread T0 = new Thread(consumer);
T0.start();

//Multiple Producers
JobProducer jobProducer = new JobProducer(jobContainer, 0, 10); 
Thread T1 = new Thread(jobProducer);
T1.start();


JobProducer jobProducer1 = new JobProducer(jobContainer, 1, 10);
Thread T2 = new Thread(jobProducer1);
T2.start();

//Join statements
T0.join();
T1.join();
T2.join();

//Stop consumer
consumer.stop(new AtomicBoolean(true));

【问题讨论】:

  • JobProducer 中有一个boolean 字段让您知道工作是否已完成怎么样?该字段以false 开头,完成工作后更改为true通知 给客户。
  • 你想让我在 main 方法中检查所有 JobProducer 的布尔字段吗?
  • 好吧,你还能做什么?这是一种非常幼稚的方法,您至少应该有一个Thread[],而不是在您的代码中有多个手动Thread x1, x2, ... xn。或者更好的是,使用已经处理此类问题的非期望ExecutorService
  • 为什么“不使用中断”?如果消费者在阻塞队列中等待,则很难以其他方式引起消费者的注意。
  • 另一方面,如果您阻止它怎么办?如果你让消费者成为一个守护线程怎么办。然后当最后一个非守护线程死亡时,JVM 会杀死它。

标签: java multithreading


【解决方案1】:

使用CountDownLatch 并为所有生产者提供足够的许可。当生产者完成生产时,它会倒计时。让一个(额外的)线程在闩上等待,然后杀死消费者/执行任何清理。

【讨论】:

  • 让一个线程杀死另一个线程是错误的形式。线程应该合作。当一个长时间运行的线程需要停止时,其他一些线程应该设置一个标志并(如果需要)中断它。然后被中断的线程应该清理它需要清理的任何东西,并从它的顶级 run() 方法返回。
【解决方案2】:

我做了一个解决方法。在main方法中,我将上述代码的最后部分修改如下,

        //Wait until all jobs are processed
        while(false == jobContainer.isEmpty()){
        synchronized(jobContainer){
        jobContainer.wait(100);
        }
    }
    //once job list is empty, stop the consumer
    calculator.stop(new AtomicBoolean(true));

注意:我也可以在 JobContainer 中移动该代码...

你们同意吗?

【讨论】:

  • 您必须将整个 while 循环移动到 synchronized 块中:synchronized(jobContainer){while(!jobContainer.isEmpty()) jobContainer.wait(100); }。对jobContainer 的所有其他访问,即从中删除项目的代码,也必须发生在synchronized(jobContainer) 块内。
猜你喜欢
  • 1970-01-01
  • 2015-07-04
  • 2017-02-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多