Java:如何中断/停止线程?

我试图阻止一个线程,但我不能这样做:

public class Middleware { public void read() { try { socket = new Socket("192.168.1.8", 2001); // code .. Scan scan = new Scan(); thread = new Thread(scan); thread.start(); } catch (UnknownHostException ex) { ex.printStackTrace(); } catch (IOException ex) { ex.printStackTrace(); } } class Scan extends Thread { public void run() { while (true) { try { // my code goes here } catch (IOException ex) { thread.currentThread().interrupt(); } } } } public void stop() { Thread.currentThread().interrupt(); } // get and setters } 

所以,即使我调用方法’停止’,线程也不会停止。 它保持活力。

我如何中断/停止此线程?

更新 (@little方法)

 private void tb_startActionPerformed(java.awt.event.ActionEvent evt) { Middleware middleware = new Middleware(); if (tb_start.getText().equals("Start")){ tb_start.setText("Stop"); // starting to read rfid tags middleware.read(); }else{ tb_start.setText("Start"); // stop reading rfid tags middleware.stop(); } } 

中间件类:

 public class Middleware { private Scan scan; public void read() { scan = new Scan(); scan.start(); } private class Scan extends Thread { @Override public void run() { while (!Thread.currentThread().isInterrupted()) { System.out.println("reading..."); } } } public void stop() { if (scan != null) { scan.interrupt(); } } } 

但是当我试图阻止线程时,它没有。 上面的代码可能有什么问题?

此致,Valter Henrique。

你真的没有理由需要使用volatile标志。 相反,只需使用isInterrupted()查询线程的状态。 另外,为什么要将Scan线程对象包装在另一个线程对象中? 这对我来说似乎完全没用。

这是’你应该做的

 public class Middleware { private Scan scan; public void read() { try { // do stuff scan = new Scan(); scan.start(); } catch (UnknownHostException ex) { // handle exception } catch (IOException ex) { // handle exception } } private class Scan extends Thread { @Override public void run() { while (!Thread.currentThread().isInterrupted()) { try { // my code goes here } catch (IOException ex) { Thread.currentThread().interrupt(); } } } } public void stop() { if(scan != null){ scan.interrupt(); } } } 

这是一个例子 。 另外,我不建议扩展Thread

简单return; 从你的while和线程将死亡,无需调用stop()或interrupt()。 如果您想在外部执行此操作,请使用此模式并调用requestStop()

 class Scan extends Thread { private volatile stop = false; public void run() { while (!stop) { try { // my code goes here } catch (IOException ex) { stop = true; } } } public void requestStop() { stop = true; } } 

停止线程的常用方法是使用volatile标志,然后在run方法中检查它。 即

 class Scan extends Thread { volatile stop = false; public void run() { while (!stop) { try { // my code goes here } catch (IOException ex) { thread.currentThread().interrupt(); } } } public void stop(){ stop = true; } } 

然后,您可以调用scan.stop()

如果要中断正在运行的线程,则需要访问该线程对象。

thread = new Thread(scan); thread.start(); 然后说

thread.interrupt();

这将中断正在运行的线程。

stop()许多用法应该被代码简单地修改一些变量来表示目标线程应该停止运行。” – java.lang.Thread

完全同意Jim ..只是添加如果您的线程在try块内被阻塞,例如在数据流上读取等,那么也会中断线程或关闭流。 在这两种情况下,应该再次唤醒线程,然后它将能够看到“stop”布尔值的变化并且通过掉出run方法自然死亡。 至少这是我在服务器的关闭线程中杀死我的线程所做的。

  public void run() { while (!Thread.currentThread().isInterrupted()) { //do something here if(condition) { Thread.currentThread().interrupt(); } } 

您可以使用外部锁定,而不是使用Thread.stop()或Thread.interrupt()。 基本上,当您尝试使用内部锁时,大多数时候您在线程上执行的任何中断都是无法控制的。

可重入锁定为您提供如下所述的方法

 lock() unlock() tryLock() lockInterruptibly() isHeldByCurrentThread() getHoldCount() 

请查看以下示例

 final ReentrantLock reentrantLock = new ReentrantLock(); @Override public void performTask() { reentrantLock.lock(); try { System.out.println(Thread.currentThread().getName() + ": Lock acquired."); System.out.println("Processing..."); Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } finally { System.out.println(Thread.currentThread().getName() + ": Lock released."); reentrantLock.unlock(); } } 

这使您的代码更优雅,并以更好的方式处理中断。