如何阻止使用匿名类创建的线程?

时间:2011-12-11 13:38:39

标签: java multithreading anonymous-types

在我的程序中,我有许多处于工作状态的线程,在方法运行中启动或通过从运行中调用其他方法。停止这些线程的方法是什么?

线程以:

启动
Runnable r = new Runnable() {
   @Override
      public void run() {
         // do something...
      }
};
new Thread(r,"Thread_1").start();

另一个可能是:

Runnable r = new Runnable() {
   @Override
      public void run() {
         startThread(); // another method called
      }
};
new Thread(r,"Thread_2").start();

停止thread_1thread_2的方法是什么?

更新

我想要的是当我点击一个按钮deactivate后面的3-4个线程应该被取消激活,以便用户可以通过再次分配任务再次启动这些线程。

5 个答案:

答案 0 :(得分:6)

Thread.stop()非常危险,强烈建议您避免使用它,原因是javadoc中所述。

尝试将邮件传递到Runnable,也许使用以下内容:

final AtomicBoolean terminate = new AtomicBoolean(false);

Runnable r = new Runnable() {
   @Override
   public void run() {
      while (!terminate.get()) {
         // do something...
      }
   }
};

new Thread(r,"Thread_1").start();
// some time later...
terminate.set(true);

您必须找到一种方法来调整变量范围,以便在您的设置下进行编译。或者,使用具有Runnable方法(或其他)的接口扩展cancel(),这是匿名类必须实现的,这与循环检查标志类似。

interface CancellableRunnable extends Runnable {
   void cancel();
}

CancellableRunnable r = new CancellableRunnable() {    
   private volatile terminate = false;

   @Override
   public void run() {
      while (!terminate) {
         // do something...
      }
   }

   @Override
   public void cancel() {
      terminate = true;
   }
}

new Thread(r,"Thread_1").start();
// some time later...
r.cancel();

答案 1 :(得分:1)

Thread类具有在java 1.0中引入的方法stop(),在java 1.1中已弃用。这种方法仍然可以工作并杀死线程。因此,如果需要,您可以停止所有线程。

但这是非常不推荐的。原因在Thread.stop()的javadoc中描述。所以最好的解决方案是修复线程的实现,使它们正确退出。但如果不可能(例如,如果这不是您的代码),您仍然需要使用Thread.stop()

答案 2 :(得分:1)

设置标志并让线程定期检查标志以驱动线程中断的问题是,如果您的线程正在调用长时间运行的API方法,或者阻塞方法,例如完整BlockingQueue上的put方法永远不会出队,因为要将它出列的线程已经关闭,或者从同样永远不会被写入的套接字中阻止读取?在所有这些情况下,这些长时间运行的调用都不会停止检查您的标志,并且您的应用程序可能会挂起。

中断线程的正确方法是在该线程实例上执行Thread.interrupt()方法,并且在运行的线程本身中,您应该定期检查Thread.currentThread()。isInterrupted()以确定线程是否应该被中断,当然捕获InterruptedException并在它被抛出时执行有序关闭。

这种方法的优点是,如果你的线程正在调用一个长时间运行的方法,希望该方法还会定期检查Thread.currentThread()。isInterrupted(),并通过有序地响应中断请求关闭然后传播InterruptedException。例如,BlockingQueue.put确实会检测Thread.interrupt()发出的中断请求。套接字不会检测到中断请求,但会响应套接字关闭,这可以在线程的重写的interrupt()方法中完成。

由于无法在匿名线程上调用interrupt()方法,因此您可能不应将它们用于长时间运行的任务。

我建议阅读“Java Concurrency in Practice”。这是一本很好的书,第7章“取消和关闭”专门讨论这类事情。它解释得比我好得多。

答案 3 :(得分:0)

如果要强制中止,可以调用stop()方法(不推荐)。只需确保您没有打开文件,执行套接字I / O,使用锁等。

更好的方法是使用while循环测试运行中的标志:

public void run() {
   while(!stop) {
      // work
   }
}

当您希望线程停止时,将stop设置为true。不要忘记volatile

答案 4 :(得分:0)

据我所知,您想知道如何检测特定的匿名线程并将其停止。 您可以尝试getCurrentThread()方法来检测线程。尽管使用stop()并不安全,但已弃用。

Thread thread = Thread.getCurrentThread();
if(thread.getName() == "Thread_1" || thread.getName() == "Thread_2")
{
thread.stop();
}