当前位置: 首页 > 面试题库 >

如何通过另一个线程停止一个线程?

邹举
2023-03-14
问题内容

我在Java中的线程上有些挣扎,我有三个线程-
线程1,线程2和线程3。那些启动时正在执行某些任务,我想通过thread1停止这两个线程。我将thread1放在sleep(500),然后停止两个线程,但是两个线程的进程仍在运行。你有什么想法吗?


问题答案:

您如何试图阻止他们?Thread.stop?警告此方法已弃用。

而是考虑对线程1使用某种标志来与线程2和3通信,它们应该停止。实际上,您可能会使用interrupts。

下面,使用Thread.interrupt来实现协调。

final Thread subject1 = new Thread(new Runnable() {

  public void run() {
    while (!Thread.interrupted()) {
      Thread.yield();
    }
    System.out.println("subject 1 stopped!");
  }
});
final Thread subject2 = new Thread(new Runnable() {

  public void run() {
    while (!Thread.interrupted()) {
      Thread.yield();
    }
    System.out.println("subject 2 stopped!");
  }
});
final Thread coordinator = new Thread(new Runnable() {

  public void run() {
    try {
      Thread.sleep(500);
    } catch (InterruptedException ex) { }
    System.out.println("coordinator stopping!");
    subject1.interrupt();
    subject2.interrupt();
  }
});
subject1.start();
subject2.start();
coordinator.start();

或者,您也可以使用volatile boolean(或AtomicBoolean)作为通信方式。
由提供的原子访问,volatilejava.util.concurrent.atomic.*允许您确保主题线程可以看到该标志的突变。

final AtomicBoolean running = new AtomicBoolean(true);

final ExecutorService subjects = Executors.newFixedThreadPool(2);
subjects.submit(new Runnable() {

  public void run() {
    while (running.get()) {
      Thread.yield();
    }
    System.out.println("subject 1 stopped!");
  }
});
subjects.submit(new Runnable() {

  public void run() {
    while (running.get()) {
      Thread.yield();
    }
    System.out.println("subject 2 stopped!");
  }
});
final ScheduledExecutorService coordinator = Executors.newSingleThreadScheduledExecutor();
coordinator.schedule(new Runnable() {

  public void run() {
    System.out.println("coordinator stopping!");
    running.set(false);
    subjects.shutdown();
    coordinator.shutdown();
  }
}, 500, TimeUnit.MILLISECONDS);

同样,您可以选择使用而不是使用AtomicBoolean,例如:

static volatile boolean running = true;

更好的是,如果您利用ExecutorService,还可以编写类似的代码,如下所示:

final ExecutorService subjects = Executors.newFixedThreadPool(2);
subjects.submit(new Runnable() {

  public void run() {
    while (!Thread.interrupted()) {
      Thread.yield();
    }
    System.out.println("subject 1 stopped!");
  }
});
subjects.submit(new Runnable() {

  public void run() {
    while (!Thread.interrupted()) {
      Thread.yield();
    }
    System.out.println("subject 2 stopped!");
  }
});
final ScheduledExecutorService coordinator = Executors.newSingleThreadScheduledExecutor();
coordinator.schedule(new Runnable() {

  public void run() {
    System.out.println("coordinator stopping!");
    subjects.shutdownNow();
    coordinator.shutdown();
  }
}, 500, TimeUnit.MILLISECONDS);

这利用了ThreadPoolExecutor.shutdownNow中断其工作线程以试图发出关闭信号这一事实。

运行任何示例,输出应具有以下效果:

C:\dev\scrap>javac CoordinationTest.java

C:\dev\scrap>java CoordinationTest
coordinator stopping!
subject 1 stopped!
subject 2 stopped!

请注意,最后两行可以任意顺序排列。



 类似资料:
  • 问题内容: 我正在用Java Swing编写应用程序。我需要的是一个可以使用图形界面中的按钮停止“阐述”线程的过程。 这里有一个简单的项目专注于我的需求 问题很简单:在实际的应用程序中,用户设置一些选项,然后启动线程,对选定的数据进行详细说明。 我想提供一个“暂停”按钮,以便用户可以暂时停止详细说明并进行必要的检查,然后可以恢复操作。 我编码的方式是停止的图形线程,而不是“精化”线程。 如果运行示

  • 我正在为这个问题寻找一个干净的设计/解决方案:我有两个线程,可以运行用户想要的时间,但最终会在用户发出停止命令时停止。然而,如果其中一个线程突然终止(例如,由于运行时异常),我想停止另一个线程。 现在,这两个线程都执行一个(因此,当我说“stop a thread”时,我的意思是对实例调用一个stop()方法),我想的是避免使用线程(thread类),并使用interface,然后将这两个Runn

  • 我如何启动两个线程,其中thread1首先执行,thread2在thread1结束时启动,而主方法线程可以在不锁定其他两个线程的情况下继续工作? 我尝试了join(),但是它需要从线程调用,线程必须等待另一个线程,没有办法执行类似thread2.join(thread1)的操作;因此,如果我在main()中调用join,我将有效地停止主线程的执行,而不仅仅是Thread2的执行。 #编辑:为什么我

  • 我是java多线程编程的新手。我知道它可以通过线程通信来完成,但我不知道如何继续。我不知道如果在文件中进行了一些更改,一个线程将如何通知另一个线程。问题在下面提到。 我有一个逗号分隔的文件,其中写入了一些行。我希望从我的主线程启动两个线程。csv文件可能会附加到外部/手动。如果csv文件中做了一些更改,其中一个线程将通知第二个线程,第二个线程将逐行并发读取该文件并执行一些任务。 谢谢

  • 以下是问题陈述: 编写一个java程序,使用线程计算前25个素数,并计算前50个斐波那契数。将计算斐波那契数的线程的优先级设置为8,将另一个设置为5。在计算了30个斐波那契数之后,让这个线程进入睡眠状态,开始计算素数。计算完25个素数后,继续斐波那契数计算。 我的代码: 我本以为当斐波那契线停止时,其余的素数会被打印出来,但那没有发生,这背后的原因可能是什么?

  • 问题内容: 我有一个主程序,其中GUI是基于swing的,并且取决于四种状态之一,GUI元素具有不同的参数。 而且,如果我想刷新,GUI只会调用具有适当参数的updateGUI,一切都很好。但是该程序还会创建一个附加线程,该线程在处理相关数据后应更改GUI主程序。不幸的是,我无法在此线程中调用方法updateGUI(..)。 我知道我可以使用invokeLater或SwingWorker进行刷新,