【问题标题】:Some questions about Threading in Java关于Java线程的一些问题
【发布时间】:2011-04-18 19:48:54
【问题描述】:

首先是一点背景。我在 NetBeans 中收到警告,告诉我不要在构造函数中启动新线程。我已经读过,这样做的原因是因为新线程可能会启动并尝试引用该对象在构造函数实际完成创建对象之前启动线程。

1.) 为了进行实验而不是使用new Threadthread.start(),我尝试了ExecutorService,但没有收到任何警告。 这是否意味着如果我使用ExecutorService,可以在构造函数中创建和启动新线程?

2.) 另外,如果我有一个缓存线程池形式的ExecutorService,将通过new Threadthread.start() 的标准方法创建一个新线程,从缓存池中拉出一个线程(或者如果一个不可用则让它创建一个)或者这些线程是否完全独立于缓存线程池?

【问题讨论】:

    标签: java multithreading threadpool executorservice


    【解决方案1】:

    1) [...] 这是否意味着如果我使用ExecutorService,可以在构造函数中创建和启动新线程?

    一般规则:在完全构造之前,不要泄漏对正在构造的对象 (this) 的引用。也就是说,不要将this 泄露给构造函数中的另一个函数,不要在构造函数中将自己添加为侦听器等……也就是说,永远不要使用this 作为参数构造函数中的函数。

    2) [...] 会通过new Threadthread.start()的标准方法从缓存池中拉出一个线程来创建一个新线程 [...]

    不,new 不可能被重载以创建一个新对象。在这种情况下,您将需要通过工厂方法。

    【讨论】:

      【解决方案2】:

      1) 不,这可能只是 NetBeans 静态分析的限制。当然,如果您不泄漏对当前正在构造的对象的引用,那么无论哪种方式都是安全的。

      泄漏对正在构造的对象的引用不仅在多线程情况下是危险的。即使您从构造函数调用外部方法,将您自己作为参数传递,该方法也可能不恰当地使用您。

      2) 不,new 总是创建一个新对象,没有例外。你正在绕着线程池转。

      【讨论】:

      • 感谢您的好回答,但 aioobe 为我简化了一点。
      【解决方案3】:

      构造函数的职责只是构造一个对象,如果你有一个扩展线程的对象,你不应该从构造函数内部调用start(),其他不同的对象应该调用start()。

      【讨论】:

        猜你喜欢
        • 2023-04-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-03-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多