Java 有人看到这个线程模式有什么问题吗?

Java 有人看到这个线程模式有什么问题吗?,java,multithreading,design-patterns,Java,Multithreading,Design Patterns,这里是一个简单的线程模式,我在编写一个只需要一个线程的类时使用它,这个类需要一个特定的任务 此类类的通常要求是它应该是可启动、可停止和可重启的。有人看到我使用的这个模式有什么问题吗 public class MyThread implements Runnable { private boolean _exit = false; private Thread _thread = null; public void start () { _exit = f

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

此类类的通常要求是它应该是可启动、可停止和可重启的。有人看到我使用的这个模式有什么问题吗

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;
        }
    }
}
如果我遗漏了什么,或者有更好的方法来写这篇文章,我会到处寻找评论

  • 使布尔标志不稳定
  • 调用stop时,不要中断线程,只需将
    \u exit
    标志设置为true
  • 如果要中断,则在while循环周围放置try/catch/finally,捕获中断异常,清理正在处理的对象的状态并退出并小心不要造成死锁
  • 最后,您可以使用一个或类似的东西来表示线程已完成

  • 另一件事是争论。。。您没有显示任何将由线程修改的内容,因此根据修改的内容,您可能必须同步(锁定等)。

    我更喜欢在“this”上使用受保护的块()。您可以通知线程很快退出循环,然后再次检查“finished”var。在通常使用Thread.sleep(x)的地方,使用this.wait(x)和一个围绕整个循环的同步(this)块。您还需要在同步(this)块中调用this.notifyAll()。

    退出变量应该是可变的。此外,遵循更正常的编码约定也是一种有用的做法。:-)

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


    可以找到一个关于Java Executors框架的好介绍。

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

    当然,用作信号量的标志也应该是可变的

    这个类的API有点奇怪。您实现了Runnable,对其他类说“使用我的run方法调用我”,但随后模拟了完整线程对象的start方法。您可能希望将run方法隐藏在内部类中。否则,您可能会对如何使用该对象感到困惑

    和往常一样,任何涉及单词
    new Thread()
    而不是使用池的模式在抽象上都有点可疑。您需要知道您实际在使用它做什么,才能对此做出明智的评论。

    1)您应该将退出声明为易失性,以防止线程可见性问题。 如果多个线程可以调用stop(),那么线程也应该是易失性的

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


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

    可能不是您想要的,但您的线程似乎会在创建后立即退出(因为_exit等于false,因此while循环永远不会发生)。我的错,我的意思是不是while(!_exit),我已经改变了这一点哦,我对这篇文章发表了评论_退出,然后在发布后,它已更改,但未显示编辑。我以为我疯了:)变量前的_在Java中是糟糕的实践和可怕的代码味道。一个更好的选择是使用这个。而不是显示成员变量和方法。显式优于隐式,隐式优于某些非标准约定;停止(),然后进一步调用
    start()将启动一个立即退出的线程。我不认为这会给直接使用
    Thread
    增加太多(正如其中一个答案所建议的那样,使用线程池和执行器服务是一个好主意,尽管这会使一些琐碎的示例需要更多地了解Java库).为什么它必须是易变的?如果他不中断线程,它会有不同。。。这样会更安全。interrupt()可能很有用。但我更喜欢“this”上的一个防护块()。您可以通知线程很快退出循环,然后再次检查“finished”var。在通常使用Thread.sleep(x)的地方,使用this.wait(x)和一个围绕整个循环的同步(this)块。您还需要处于同步(this)块中才能调用此.notifyAll()。如果我在run()中有阻塞调用,那将无限期阻塞。我用中断退出这些调用。@prmatta,就像我说的。。。如果需要中断,则捕获InterruptException并正确清理。此外,如果在锁的中间中断,则可能导致死锁。他的类实现可运行的…他没有实现线程。他称之为MyThread,但它没有实现线程。他有一个字段,它是线程。不管是扩展还是编写,他仍然直接引用类。创建自己的线程本身并没有什么错,尽管我同意应该优先选择执行者。@Lirik:完全同意-这不是一个硬性规定。有时,一个一次性的、快速实现的线程是最好的解决方案。通常,您希望将要执行的任务的责任与并发性和线程问题分开。