这是一个简单的线程模式,我在编写一个只需要一个线程的类时使用,并且需要一个特定的任务。
这类的通常要求是它应该是可启动的,可停止的和可重启的。有没有人看到我使用这种模式的任何问题?
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;
}
}
}
我正在寻找有关我是否遗漏某些内容的评论,或者是否有更好的方式来写这篇文章。
答案 0 :(得分:6)
我建议不要直接使用Thread类。自Java 5以来可用的Executors框架简化了线程中涉及的许多问题。我们的想法是,您的类将执行所需的任务,并且所有线程功能都由Executor管理,从而为您节省处理线程复杂性的工作。
可以在Java Executors框架上找到一个好的介绍here。
答案 1 :(得分:2)
_exit
标志设置为true。另一件事是争论......你没有展示任何会被线程修改的东西,所以根据修改的内容你可能需要同步(锁等等)。
答案 2 :(得分:2)
嗯,类本身不是线程安全的。只要在代码中记录和观察到这一点,这就不一定是个问题。如果不是,你可能会丢失对并行运行的Thread对象的引用,如果两个使用者同时进入start()方法。
用作信号量的标志当然也应该是易变的。
该类的API有点奇怪。你实现了Runnable,对其他类说“使用我的run方法来调用我”,然后模仿完整Thread对象的start方法。您可能希望在内部类中隐藏run方法。否则,如何打算使用该对象会让人感到困惑。
与往常一样,任何涉及单词new Thread()
而不是使用池的模式在抽象中都有些怀疑。需要知道你实际上在做什么才能真正对此进行智能评论。
答案 3 :(得分:1)
1)您应该将_exit声明为volatile以防止线程可见性问题。 如果多个线程可能调用stop(),则_thread也应该是volatile。
2)对中断的调用只会为可中断的阻塞操作抛出InterruptedException。您可能需要采取更多操作,具体取决于您在线程中执行的阻止操作
3)如果希望类实例可重用,则应在start()方法中将_exit设置为false。
答案 4 :(得分:0)
我更喜欢在'this'上设置一个防护块(http://java.sun.com/docs/books/tutorial/essential/concurrency/guardmeth.html)。您可以非常快速地通知线程退出循环,然后再次检查'finished'var。在通常使用Thread.sleep(x)的地方,你可以在整个循环中使用this.wait(x)和一个synchronized(this)块。您还需要在同步(此)块中调用this.notifyAll()。
答案 5 :(得分:0)
_exit变量应该是volatile。此外,遵循更正常的编码约定将是有用的实践。 : - )