代码之家  ›  专栏  ›  技术社区  ›  rouble

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

  •  3
  • rouble  · 技术社区  · 14 年前

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

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

    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 回复  |  直到 14 年前
        1
  •  2
  •   Affe    14 年前

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

    当然,用作信号量的标志也应该是易失的。

    这个类的API有点奇怪。您可以实现runnable,对其他类说“使用我的run方法来调用我”,然后模仿一个完整线程对象的start方法。您可能希望将run方法隐藏在内部类中。否则,它会让人有点困惑如何使用对象。

    和往常一样,任何涉及单词的模式 new Thread() 抽象地说,与其使用池,不如使用池。需要知道你在用它做什么,才能对它作出明智的评论。

        2
  •  6
  •   Grundlefleck anujkk    14 年前

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

    可以在Java执行器框架上找到一个好的介绍 here .

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

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

        4
  •  1
  •   Eyal Schneider    14 年前

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

    2)对interrupt的调用将只对可中断的阻塞操作抛出interruptedException。根据您在线程中执行的阻塞操作,可能需要采取更多的操作。

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

        5
  •  0
  •   dty    14 年前

    exit变量应该是volatile。此外,遵循更正常的编码约定也是很有用的实践。-)

        6
  •  0
  •   Chris Dennett    14 年前

    我喜欢有人看守的街区( http://java.sun.com/docs/books/tutorial/essential/concurrency/guardmeth.html 关于“这个”。您可以通知线程很快从循环中退出,然后再次检查“finished”var。在通常使用thread.sleep(x)的地方,使用this.wait(x),在整个循环中使用synchronized(this)块。您还需要处于同步(此)块中才能调用此.notifyAll()。