changeset 434:34dd517c7183

6926623: Thread clone issues Reviewed-by: hawtin
author chegar
date Wed, 30 Jun 2010 16:51:19 +0100
parents 9242f7e22b5d
children 1f9e4b58a1f9
files src/share/classes/java/lang/Thread.java
diffstat 1 files changed, 43 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/classes/java/lang/Thread.java	Wed Jun 30 11:15:38 2010 +0400
+++ b/src/share/classes/java/lang/Thread.java	Wed Jun 30 16:51:19 2010 +0100
@@ -253,6 +253,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.
      *
@@ -379,9 +383,46 @@
 
         /* 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;
+    }
+
+    /**
      * Allocates a new <code>Thread</code> object. This constructor has
      * the same effect as <code>Thread(null, null,</code>
      * <i>gname</i><code>)</code>, where <b><i>gname</i></b> is
@@ -608,7 +649,7 @@
          *
          * A zero status value corresponds to state "NEW".
          */
-        if (threadStatus != 0)
+        if (threadStatus != 0 || this != me)
             throw new IllegalThreadStateException();
         group.add(this);
         start0();