3
/**
 * 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 class documentation says that Thread can not be meaningfully cloned. What does this means?

Sotirios Delimanolis
  • 274,122
  • 60
  • 696
  • 724
  • 2
    Well, how *would* you clone a thread? – Kayaman Jul 04 '16 at 18:26
  • Throws CloneNotSupportedException as a Thread can not be meaningfully cloned. https://docs.oracle.com/javase/7/docs/api/java/lang/Thread.html#clone() – PVR Jul 04 '16 at 18:27
  • Why would you want to clone a thread? What should be the semantics (the result) if you clone the currently running thread? If you clone a thread that holds a monitor? You can probably find even more interesting questions. – Ole V.V. Jul 05 '16 at 14:36

2 Answers2

7

A thread is closely related to state and mechanisms managed within the jvm, perhaps even also resources tied to the underlying implementation of the operating system.

And so cloning a Thread's state without going through the normal thread startup / shutdown mechanisms would give unpredictable results at best, or a fatal jvm crash at worst.

Given the code you discovered, it's pretty obvious that you're not meant to do this, it's a "bad idea" (tm) ;)

vikingsteve
  • 38,481
  • 23
  • 112
  • 156
1

Like the documentation says, it doesn't make sense to clone a thread, if you want another thread you'd create a new one.

If you are in the position of wanting to clone a Thread, that suggests you have extended Thread where you should have implemented Runnable, or else you have otherwise managed to tie your domain objects to Thread somehow. For instance, there is an unfortunate anti-pattern where people create a class that implements Runnable, then create a Thread as an instance member of this class like this:

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

This is a great example of blindly following best-practices in a way that misses the point entirely. While superficially this follows advice about implementing Runnable rather than subclassing Thread, tying the task to the specific Thread that executes it defeats the purpose of that advice, which is intended to facilitate decoupling the task from how it is executed.

Tasks that need to be run independently or asynchronously shouldn't have to know about Thread, it's better to design them so that they can be run by an executor service instead. There are two interfaces, Runnable and Callable, which are provided in order to allow you to specify tasks in a way that doesn't tie them to a specific means of execution, as opposed to subclassing Thread, where you have tied your task to a specific Thread object. That way you have the freedom to change how they are executed without changing the task, and you also will have the freedom to create tasks that are Cloneable, since no Thread will be involved.

Nathan Hughes
  • 94,330
  • 19
  • 181
  • 276