Java 子线程如何通知父线程终止所有其他子线程

Java 子线程如何通知父线程终止所有其他子线程,java,multithreading,Java,Multithreading,我的问题如下 一个父线程创建5个子线程,所有子线程开始查找结果,一个子线程得到结果。它必须通知父线程它得到了结果,并终止所有其他子线程。这样做是不明智的。只需对子线程进行编码,以停止执行不再需要执行的工作。每当你发现自己在问“我怎样才能从外部推动我的代码来满足我的需要?”时,停下来纠正自己。正确的问题是,“我如何编写代码来完成我一开始想要它做的事情,这样我就不必从外部推动它了?”这不是一种明智的方法。只需对子线程进行编码,以停止执行不再需要执行的工作。每当你发现自己在问“我怎样才能从外部推动我的

我的问题如下


一个父线程创建5个子线程,所有子线程开始查找结果,一个子线程得到结果。它必须通知父线程它得到了结果,并终止所有其他子线程。这样做是不明智的。只需对子线程进行编码,以停止执行不再需要执行的工作。每当你发现自己在问“我怎样才能从外部推动我的代码来满足我的需要?”时,停下来纠正自己。正确的问题是,“我如何编写代码来完成我一开始想要它做的事情,这样我就不必从外部推动它了?”

这不是一种明智的方法。只需对子线程进行编码,以停止执行不再需要执行的工作。每当你发现自己在问“我怎样才能从外部推动我的代码来满足我的需要?”时,停下来纠正自己。正确的问题是,“我如何编写代码来完成我首先希望它完成的任务,这样我就不必从外部将其推来推去?”

设置子项以更新父项中的字段(如果该字段不为空)。让孩子们偶尔检查一下字段是否为空。如果不是,他们应该停止


这行吗?

如果父字段不为空,则设置子字段以更新该字段。让孩子们偶尔检查一下字段是否为空。如果不是,他们应该停止


这行吗?

我觉得由子线程终止其他子线程是完全可以接受的。尤其是当子线程使用阻塞方法时。您只需要一个可由子级访问的父级
stop
方法

比如:

public interface Stopable {
  public void stop ();
}

public class Child
    extends Thread {
  final Stopable parent;
  boolean foundAnswer = false;

  Child ( Stopable parent ) {
    this.parent = parent;
  }

  public void run () {
    try {
      while ( !isInterrupted() ) {
        // Do some work.
        work();

        if ( foundAnswer ) {
          // Stop everyone.
          parent.stop();
        }
      }
    } catch ( InterruptedException ie ) {
      // Just exit when interrupted.
    }
  }

  private void work () throws InterruptedException {
    while ( !foundAnswer ) {
      // Do some work.

      // Should we stop now?
      checkForInterrupt ();
    }
  }

  private void checkForInterrupt () throws InterruptedException {
    if ( isInterrupted() ) {
      throw new InterruptedException();
    }
  }

}

public class Mainthread
    implements Stopable {
  ArrayList<Child> children = new ArrayList<Child> ();

  public void go () {
    // Spawn a number of child threads.
    for ( int i = 0; i < 5; i++ ) {
      Child newChild = new Child( this );
      children.add( newChild );
      newChild.start();
    }
  }

  public void stop () {
    // Interrupt/kill all child threads.
    for ( Child c : children ) {
      c.interrupt();
    }
  }
}
公共接口可停止{
公众停车场();
}
公营儿童
延长线程{
最终可终止父代;
布尔值foundAnswer=false;
子级(可停止的父级){
this.parent=parent;
}
公开作废运行(){
试一试{
而(!isInterrupted()){
//做一些工作。
工作();
如果(找到答案){
//阻止所有人。
parent.stop();
}
}
}捕获(中断异常ie){
//被打断时退出。
}
}
私有void work()抛出InterruptedException{
而(!foundAnswer){
//做一些工作。
//我们现在应该停下来吗?
checkForInterrupt();
}
}
私有void checkForInterrupt()抛出InterruptedException{
如果(isInterrupted()){
抛出新的InterruptedException();
}
}
}
公共类主线程
可停止的机具{
ArrayList子项=新的ArrayList();
公开作废go(){
//生成许多子线程。
对于(int i=0;i<5;i++){
Child newChild=新子女(本);
添加(newChild);
newChild.start();
}
}
公众停车场(){
//中断/终止所有子线程。
儿童(c:儿童){
c、 中断();
}
}
}

我觉得由子线程终止其他子线程是完全可以接受的。尤其是当子线程使用阻塞方法时。您只需要一个可由子级访问的父级
stop
方法

比如:

public interface Stopable {
  public void stop ();
}

public class Child
    extends Thread {
  final Stopable parent;
  boolean foundAnswer = false;

  Child ( Stopable parent ) {
    this.parent = parent;
  }

  public void run () {
    try {
      while ( !isInterrupted() ) {
        // Do some work.
        work();

        if ( foundAnswer ) {
          // Stop everyone.
          parent.stop();
        }
      }
    } catch ( InterruptedException ie ) {
      // Just exit when interrupted.
    }
  }

  private void work () throws InterruptedException {
    while ( !foundAnswer ) {
      // Do some work.

      // Should we stop now?
      checkForInterrupt ();
    }
  }

  private void checkForInterrupt () throws InterruptedException {
    if ( isInterrupted() ) {
      throw new InterruptedException();
    }
  }

}

public class Mainthread
    implements Stopable {
  ArrayList<Child> children = new ArrayList<Child> ();

  public void go () {
    // Spawn a number of child threads.
    for ( int i = 0; i < 5; i++ ) {
      Child newChild = new Child( this );
      children.add( newChild );
      newChild.start();
    }
  }

  public void stop () {
    // Interrupt/kill all child threads.
    for ( Child c : children ) {
      c.interrupt();
    }
  }
}
公共接口可停止{
公众停车场();
}
公营儿童
延长线程{
最终可终止父代;
布尔值foundAnswer=false;
子级(可停止的父级){
this.parent=parent;
}
公开作废运行(){
试一试{
而(!isInterrupted()){
//做一些工作。
工作();
如果(找到答案){
//阻止所有人。
parent.stop();
}
}
}捕获(中断异常ie){
//被打断时退出。
}
}
私有void work()抛出InterruptedException{
而(!foundAnswer){
//做一些工作。
//我们现在应该停下来吗?
checkForInterrupt();
}
}
私有void checkForInterrupt()抛出InterruptedException{
如果(isInterrupted()){
抛出新的InterruptedException();
}
}
}
公共类主线程
可停止的机具{
ArrayList子项=新的ArrayList();
公开作废go(){
//生成许多子线程。
对于(int i=0;i<5;i++){
Child newChild=新子女(本);
添加(newChild);
newChild.start();
}
}
公众停车场(){
//中断/终止所有子线程。
儿童(c:儿童){
c、 中断();
}
}
}

但是如果我调用父类的方法来终止所有线程,这将增加性能开销,那么我认为这会起作用,但我不知道父线程如何终止java+1中的所有子线程,尽管与对象上的null测试相比,volatile boolean是更好的选择(布尔变量表示条件,对象变量不表示条件)。@user1047873-是的,这会增加一些微小的开销。但是终止线程的唯一干净方法是使用标志。不要使用thread.stop(),它被弃用是有原因的。这只是中断标志的一个有缺陷的重新实现。但是如果我调用父类的方法来终止所有线程,这将增加性能开销,那么我认为它会工作,但我不知道父线程如何终止java+1中的所有子线程,尽管易变布尔值是一个赌注比在对象上进行空测试(布尔变量表示条件,对象变量不表示条件)更好的选择。@user1047873-是的,这会增加一些微小的开销。但是终止线程的唯一干净方法是使用标志。不要使用thread.stop(),它被弃用是有原因的。这只是一个有缺陷的中断标志的重新实现。如果我今天戴着我的脾气暴躁的帽子,我会称之为手动操作…但我没有,所以我不会;)。如果