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

时间:2010-06-10 18:57:42

标签: java multithreading design-patterns

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

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

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;
        }
    }
}

我正在寻找有关我是否遗漏某些内容的评论,或者是否有更好的方式来写这篇文章。

6 个答案:

答案 0 :(得分:6)

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

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

答案 1 :(得分:2)

  1. 使布尔标志易失。
  2. 当你调用stop时不要中断线程,只需将_exit标志设置为true。
  3. 如果你要打断,那么在while循环周围放一个try / catch / finally并捕获中断异常,清理你正在使用的对象的状态并退出。 小心不要造成僵局!
  4. 最后,您可以使用CountDownLatch或类似的东西,以表示线程已完成。
  5. 另一件事是争论......你没有展示任何会被线程修改的东西,所以根据修改的内容你可能需要同步(锁等等)。

答案 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。此外,遵循更正常的编码约定将是有用的实践。 : - )