/**
* Throws CloneNotSupportedException as a Thread can not be meaningfully
* cloned. Construct a new Thread instead.
*
* @throws CloneNotSupportedException
* always
*/
@Override
protected Object clone() throws CloneNotSupportedException {
throw new CloneNotSupportedException();
}
线程类文档说无法有意义地克隆线程。这意味着什么?
答案 0 :(得分:6)
线程与jvm中管理的状态和机制密切相关,甚至可能是与操作系统底层实现相关的资源。
所以克隆一个Thread的状态而不经过正常的线程启动/关闭机制会最多给出不可预测的结果,或者最坏的情况下致命的jvm崩溃。
鉴于您发现的代码,很明显您不打算这样做,这是一个“坏主意”(tm);)
答案 1 :(得分:1)
就像文档所说的那样,如果你想要另一个线程你创建一个新线程,那么克隆线程没有意义。
如果您处于想要克隆线程的位置,那表明您已经扩展了Thread应该已经实现了Runnable,否则您已经设法将您的域对象以某种方式绑定到Thread。例如,有一个不幸的反模式,人们创建一个实现Runnable的类,然后创建一个Thread作为这个类的实例成员,如下所示:
// Example of anti-pattern, please don't do this!
class MyTask implements Runnable {
private Thread thread;
public void start() {
thread = new Thread(this);
thread.start();
}
public void run() {
// whatever code your task performs
}
}
这是盲目追随最佳实践的一个很好的例子,完全忽略了这一点。虽然表面上遵循了关于实现Runnable而不是子类化Thread的建议,但将任务绑定到执行它的特定Thread会破坏该建议的目的,这旨在促进任务与其执行方式的分离。
需要独立或异步运行的任务不应该了解Thread,最好设计它们,以便它们可以由执行程序服务运行。有两个接口,Runnable和Callable,它们是为了允许您以不与特定执行方式相关联的方式指定任务,而不是子类化Thread,您已将任务绑定在哪里到特定的Thread对象。这样你就可以自由地改变它们的执行方式,而不需要改变任务,你也可以自由创建Cloneable任务,因为不会涉及Thread。
答案 2 :(得分:-1)
clone方法继承自Object类,其中Object类不实现Cloneable Interface;因此,使用JDK文档:
“抛出此异常表示已调用类Object中的clone方法来克隆对象,但该对象的类未实现Cloneable接口。” ref
因此,在java中创建的每个Object都有一个克隆方法,但并不意味着它们实现了Cloneable Interface;我个人认为,这种方法让开发人员有机会确定什么是可克隆的,如果你需要实际克隆整个Object,你必须实现Cloneable。
干杯。