有没有人看到这个线程模式有任何问题?

这是一个简单的线程模式,我在编写一个只需要一个线程的类时使用,并且需要一个特定的任务。

这类的通常要求是它应该是可启动的,可停止的和可重启的。 有没有人看到我使用这种模式的任何问题?

public class MyThread implements Runnable { private boolean _exit = false; private Thread _thread = null; public void start () { _exit = false; if (_thread == null) { _thread = new Thread(this, "MyThread"); _thread.start(); } } public void run () { while (!_exit) { //do something } } public void stop () { _exit = true; if (_thread != null) { _thread.interrupt(); _thread = null; } } } 

如果我遗漏某些东西,或者有更好的方法来写这个,我正在寻找评论。

好吧,类本身不是线程安全的。 只要在代码中记录和观察到这一点,这就不一定是个问题。 如果不是,您可能会丢失对将并行运行的Thread对象的引用,如果两个使用者同时进入start()方法。

用作信号量的标志当然也应该是挥发性的。

该类的API有点奇怪。 你实现了Runnable,对其他类说“使用我的run方法来调用我”,然后模仿完整Thread对象的start方法。 您可能希望在内部类中隐藏run方法。 否则,如何打算使用该对象会让人感到困惑。

和往常一样,任何涉及单词new Thread()而不是使用池的模式在抽象中都有些怀疑。 需要知道你实际上在做什么才能真正对此进行智能评论。

我建议不要直接使用Thread类。 自Java 5以来可用的Executors框架简化了线程中涉及的许多问题。 我们的想法是,您的类将执行所需的任务,并且所有线程function都由Executor管理,从而为您节省处理线程复杂性的工作。

可以在此处找到Java Executors框架上的一个好的介绍。

  1. 使布尔标志不稳定。
  2. 当你调用stop时不要中断线程,只需将_exit标志设置为true即可。
  3. 如果你要打断,那么在while循环周围放一个try / catch / finally并捕获中断exception,清理你正在使用的对象的状态并退出。 小心不要造成僵局!
  4. 最后,您可以使用CountDownLatch或类似的东西,以表示线程已完成。

另一件事是争论……你没有展示任何会被线程修改的东西,所以根据修改的内容你可能需要同步(锁等等)。

1)您应该将_exit声明为volatile以防止线程可见性问题。 如果多个线程可能调用stop(),则_thread也应该是volatile。

2)对中断的调用将仅针对可中断的阻塞操作抛出InterruptedException。 您可能需要采取更多操作,具体取决于您在线程中执行的阻止操作

3)如果希望类实例可重用,则应在start()方法中将_exit设置为false。

_exit变量应该是volatile。 此外,遵循更正常的编码约定将是有用的实践。 🙂

我更喜欢’this’上的防护块( http://java.sun.com/docs/books/tutorial/essential/concurrency/guardmeth.html )。 您可以非常快速地通知线程退出循环,然后再次检查’finished’var。 在通常使用Thread.sleep(x)的地方,你可以在整个循环中使用this.wait(x)和一个synchronized(this)块。 您还需要在同步(此)块中调用this.notifyAll()。