为什么Thread类不支持克隆方法?

时间:2016-07-04 18:25:15

标签: java multithreading cloning

/**
 * 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();
}

线程类文档说无法有意义地克隆线程。这意味着什么?

3 个答案:

答案 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。

干杯。