2016-07-04 57 views
2
/** 
* 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(); 
} 

线程类文档说明线程无法被有意克隆。这是什么意思?为什么Thread类不支持克隆方法?

+2

那么,你会如何克隆一个线程? – Kayaman

+0

抛出CloneNotSupportedException,因为线程无法被有意克隆。 https://docs.oracle.com/javase/7/docs/api/java/lang/Thread.html#clone() – PVR

+0

为什么要克隆一个线程?如果克隆当前正在运行的线程,应该是什么语义(结果)?如果你克隆一个拥有显示器的线程?你可能会发现更有趣的问题。 –

回答

5

线程与在jvm中管理的状态和机制密切相关,甚至可能与操作系统的底层实现有关。

因此,如果不通过正常的线程启动/关闭机制来克隆线程的状态,最多可能会导致不可预知的结果,或者最糟糕的是致命的jvm崩溃。

给你发现的代码,这是很明显,你不是要做到这一点,这是一个“坏主意”(TM))

-1

克隆方法是从Object类继承,其中对象类不实现Cloneable接口;因此,使用JDK文档:

“抛出以指示已调用Object类中的克隆方法来克隆对象,但该对象的类不实现Cloneable接口。 ref

因此,在java中创建的每个Object都有一个克隆方法,但并不意味着它们实现了Cloneable Interface;我个人认为,这种方法为开发人员提供了确定什么是可复制或不可复制的机会,如果您需要实际克隆整个对象,则必须实现Cloneable。

干杯。

1

就像文档说的那样,如果你想要创建一个新线程的话,克隆一个线程是没有意义的。

如果您希望克隆一个线程的位置,这表明您已经扩展了线程,您应该已经实现了Runnable,否则您已经设法将您的域对象绑定到线程。例如,有时人们创建一个实现Runnable类的不幸的反模式,然后创建一个线程为这个类的一个这样的实例成员:

// 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 
    } 
} 

这是盲从BEST-一个很好的例子以一种完全忽略这一点的方式实践。虽然从表面上看,这遵循了关于实现Runnable而不是子类化Thread的建议,但将任务绑定到执行它的特定Thread会违反该建议的目的,该建议旨在帮助将任务从执行方式中分离出来。

需要独立运行或异步运行的任务不必知道线程,最好设计它们以便它们可以由执行程序服务运行。有两个接口,Runnable和Callable,这些接口是为了让你指定任务的方式不是将它们绑定到特定的执行方式而提供的,而不是将子任务绑定到Thread,在这里你将任务绑定到特定的Thread对象。这样你就可以自由地改变它们在不改变任务的情况下被执行的方式,而且你也可以自由地创建可克隆的任务,因为不会涉及任何线程。