关于Java线程的一些问题
首先介绍一点背景。我在 NetBeans 中收到警告,告诉我不要在构造函数中启动新线程。我读过,其原因是因为新线程可能会启动并尝试引用在构造函数实际完成创建对象之前启动线程的对象。
1.) 为了进行实验,我没有使用 new Thread
和 thread.start()
,而是尝试了 ExecutorService
并且没有收到任何警告。 这是否意味着如果我使用 ExecutorService
就可以在构造函数中创建并启动新线程?
2.) 另外,如果我有一个 ExecutorService 以缓存线程池的形式会通过标准方法 new Thread
创建一个新线程,并从缓存中拉出一个线程 thread.start()
池(或者如果没有可用则导致它创建一个)或者这些线程是否完全独立于缓存的线程池?
First a little background. I got a warning in NetBeans told me not to start a new thread in a constructor. I have read that the reason for that is because the new thread might start and try to reference the object started the thread before the constructor is actually done making the object.
1.) For the sake of experimentation instead of using new Thread
and thread.start()
I tried ExecutorService
and I got no warning. Does this mean it is ok to create and start a new thread in a constructor if I use ExecutorService
?
2.) Also, if I have an ExecutorService
in the form of a cached thread pool will the creation of a new thread by the standard method of new Thread
and thread.start()
pull a thread from the cache pool (or cause it to create one if one is not available) or are those threads completely independent of the cached thread pool?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
一般规则:不要泄漏引用正在构造的对象 (
this
),直到它完全构造完毕。也就是说,不要将this
交给构造函数中的另一个 therad,不要将自己添加为构造函数中的侦听器,等等,等等...也就是说,永远不要使用this
作为构造函数中函数的参数。不,
new
不可能被重载而不创建一个新的对象。在这种情况下,您将需要使用工厂方法。General rule: Don't leak the reference to the object being constructed (
this
) until it is fully constructed. That is, don't give awaythis
to another therad in the constructor, don't add yourself as a listener from within the constructor, etc, etc... That is, never usethis
as a parameter to a function from within the constructor.No, there is no way
new
could have been overloaded to not create a fresh object. In such cases you will need to go through a factory method.1) 不,这可能只是 NetBeans 静态分析的限制。当然,如果您不泄漏对当前正在构造的对象的引用,那么无论哪种方式都是安全的。
泄漏对正在构造的对象的引用不仅在多线程情况下很危险。即使您从构造函数调用外部方法,并将您自己作为参数传递,该方法也可能会不适当地使用您。
2) 不,
new
总是创建一个新对象,没有例外。您正在绕过线程池。1) No, it's probably just a limitation of NetBeans' static analysis. Of course it's safe to do either way if you don't leak a reference to the object currently being constructed.
Leaking a reference to an object being constructed isn't only dangerous in multi-threaded situations, either. Even if you call an external method from the constructor, passing yourself as a parameter, the method could use you inappropriately.
2) No,
new
always creates a new object, no exceptions. You are going around the thread pool.构造函数的职责只是构造一个对象,如果你有一个扩展Thread的对象,你不应该从构造函数内部调用start(),其他不同的对象应该调用start()。
The constructor duty is just to construct an object, if you have an object that extend Thread, you shouldn't call to start() from inside the constructor, other different object should call start().