# HG changeset patch # User chegar # Date 1277911477 -3600 # Node ID 3e770ac705b6590fd221a28ab0e83193fb2149b7 # Parent e7987a9205f42964c0aeaa626745c17ad54415fb# Parent 4197c5af089dcd84663e0a0d40728010162f3193 Merge diff -r e7987a9205f4 -r 3e770ac705b6 jdk/src/share/classes/java/lang/Thread.java --- a/jdk/src/share/classes/java/lang/Thread.java Wed Jun 30 11:32:38 2010 +0400 +++ b/jdk/src/share/classes/java/lang/Thread.java Wed Jun 30 16:24:37 2010 +0100 @@ -260,6 +260,10 @@ /* Remembered Throwable from stop before start */ private Throwable throwableFromStop; + /* Whether or not the Thread has been completely constructed; + * init or clone method has successfully completed */ + private volatile Thread me; // null + /** * Returns a reference to the currently executing thread object. * @@ -411,6 +415,43 @@ /* Set thread ID */ tid = nextThreadID(); + + this.me = this; + } + + /** + * Returns a clone if the class of this object is {@link Cloneable Cloneable}. + * + * @return a clone if the class of this object is {@code Cloneable} + * + * @throws CloneNotSupportedException + * if this method is invoked on a class that does not + * support {@code Cloneable} + */ + @Override + protected Object clone() throws CloneNotSupportedException { + Thread t; + synchronized(this) { + t = (Thread) super.clone(); + + t.tid = nextThreadID(); + t.parkBlocker = null; + t.blocker = null; + t.blockerLock = new Object(); + t.threadLocals = null; + + group.checkAccess(); + group.addUnstarted(); + t.setPriority(priority); + + final Thread current = Thread.currentThread(); + if (current.inheritableThreadLocals != null) + t.inheritableThreadLocals = + ThreadLocal.createInheritedMap(current.inheritableThreadLocals); + } + + t.me = t; + return t; } /** @@ -672,7 +713,7 @@ * * A zero status value corresponds to state "NEW". */ - if (threadStatus != 0) + if (threadStatus != 0 || this != me) throw new IllegalThreadStateException(); /* Notify the group that this thread is about to be started