Save This Page
Home » apache-harmony-6.0-src-r917296-snapshot » java » lang » [javadoc | source]
    1   /*
    2    *  Licensed to the Apache Software Foundation (ASF) under one or more
    3    *  contributor license agreements.  See the NOTICE file distributed with
    4    *  this work for additional information regarding copyright ownership.
    5    *  The ASF licenses this file to You under the Apache License, Version 2.0
    6    *  (the "License"); you may not use this file except in compliance with
    7    *  the License.  You may obtain a copy of the License at
    8    *
    9    *     http://www.apache.org/licenses/LICENSE-2.0
   10    *
   11    *  Unless required by applicable law or agreed to in writing, software
   12    *  distributed under the License is distributed on an "AS IS" BASIS,
   13    *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   14    *  See the License for the specific language governing permissions and
   15    *  limitations under the License.
   16    */
   17   /**
   18    * @author Roman S. Bushmanov
   19    */
   20   
   21   package java.lang;
   22   
   23   import java.security.AccessController;
   24   import java.util.HashMap;
   25   import java.util.IdentityHashMap;
   26   import java.util.Iterator;
   27   import java.util.Map;
   28   
   29   import org.apache.harmony.lang.RuntimePermissionCollection;
   30   import org.apache.harmony.security.fortress.SecurityUtils;
   31   import org.apache.harmony.vm.VMStack;
   32   
   33   /**
   34    * @com.intel.drl.spec_ref 
   35    */
   36   public class Thread implements Runnable {
   37   
   38       /**
   39        * @com.intel.drl.spec_ref
   40        */
   41       public static final int MAX_PRIORITY = 10;
   42   
   43       /**
   44        * @com.intel.drl.spec_ref
   45        */
   46       public static final int MIN_PRIORITY = 1;
   47   
   48       /**
   49        * @com.intel.drl.spec_ref
   50        */
   51       public static final int NORM_PRIORITY = 5;
   52   
   53       /**
   54        * Indent string used to print stack trace
   55        */
   56       private static final String STACK_TRACE_INDENT = "    ";
   57   
   58       /**
   59        * This thread's thread group
   60        */
   61       ThreadGroup group;
   62   
   63       /**
   64        * This thread's context class loader
   65        */
   66       private ClassLoader contextClassLoader;
   67   
   68       /**
   69        * Indicates whether this thread was marked as daemon
   70        */
   71       private boolean daemon;
   72   
   73       /**
   74        * Thread's name
   75        */
   76       private String name;
   77   
   78       /**
   79        * Thread's priority
   80        */
   81       private int priority;
   82   
   83       /**
   84        * Stack size to be passed to VM for thread execution
   85        */
   86       private long stackSize;
   87   
   88       /**
   89        * Indicates if the thread was already started
   90        */
   91       boolean started = false;
   92   
   93       
   94       /**
   95        * Indicates if the thread is alive.
   96        */
   97       boolean isAlive = false;
   98   
   99       /**
  100        * Thread's target - a <code>Runnable</code> object whose <code>run</code>
  101        * method should be invoked
  102        */
  103       private Runnable target;
  104   
  105   
  106       /**
  107        * Uncaught exception handler for this thread
  108        */
  109       private UncaughtExceptionHandler exceptionHandler = null;
  110   
  111       /**
  112        * Default uncaught exception handler
  113        */
  114       private static UncaughtExceptionHandler defaultExceptionHandler = null;
  115   
  116       /**
  117        * Thread's ID
  118        */
  119       private long threadId;
  120   
  121       /**
  122        * Counter used to generate thread's ID
  123        */
  124       private static long threadOrdinalNum = 0;
  125   
  126       /**
  127        * Synchronization is done using internal lock.
  128        */
  129       Object lock = new Object();
  130   
  131       /**
  132        * used to generate a default thread name
  133        */
  134       private static final String THREAD = "Thread-";
  135   
  136       /**
  137        * System thread group for keeping helper threads.
  138        */
  139       static ThreadGroup systemThreadGroup = null;
  140       
  141       /**
  142        * Main thread group.
  143        */
  144       static ThreadGroup mainThreadGroup = null;
  145   
  146       /*
  147        * Number of threads that was created w/o garbage collection.
  148        */ 
  149       private static int currentGCWatermarkCount = 0;
  150   
  151       /*
  152        * Max number of threads to be created w/o GC, required collect dead Thread 
  153        * references.
  154        */
  155       private static final int GC_WATERMARK_MAX_COUNT = 700;
  156   
  157       /*
  158        * ThreadLocal values: local and inheritable
  159        *
  160        */
  161       ThreadLocal.Values localValues;
  162       ThreadLocal.Values inheritableValues;
  163       
  164       /**
  165        * @com.intel.drl.spec_ref
  166        */
  167       public Thread() {
  168           this(null, null, THREAD, 0);
  169       }
  170   
  171       /**
  172        * @com.intel.drl.spec_ref
  173        */
  174       public Thread(Runnable target) {
  175           this(null, target, THREAD, 0);
  176       }
  177   
  178       /**
  179        * @com.intel.drl.spec_ref
  180        */
  181       public Thread(Runnable target, String name) {
  182           this(null, target, name, 0);
  183       }
  184   
  185       /**
  186        * @com.intel.drl.spec_ref
  187        */
  188       public Thread(String name) {
  189           this(null, null, name, 0);
  190       }
  191   
  192       /**
  193        * @com.intel.drl.spec_ref
  194        */
  195       public Thread(ThreadGroup group, Runnable target) {
  196           this(group, target, THREAD, 0);
  197       }
  198   
  199       /**
  200        * @com.intel.drl.spec_ref
  201        */
  202       public Thread(ThreadGroup group, Runnable target, String name) {
  203           this(group, target, name, 0);
  204       }
  205   
  206       /**
  207        * Creates a new thread object for the thread attached to VM.     
  208        * The first attached thread is the main thread.
  209        *
  210        * @param group determines the thread group to place the thread in
  211        * @param name thread's name
  212        * @param nativeAddr address of the attached native thread
  213        * @param stackeSize size of the thread's stack
  214        * @param priority thread's priority
  215        * @param daemon true if the thread is daemon, false otherwise
  216        */
  217       Thread(ThreadGroup group, String name, long nativeAddr,
  218           long stackSize, int priority, boolean daemon) {
  219   
  220           ClassLoader contextLoader = null;
  221           
  222           if (group == null) {
  223               if (systemThreadGroup == null) {
  224                   // This is main thread.
  225                   systemThreadGroup = new ThreadGroup();
  226                   mainThreadGroup = new ThreadGroup(systemThreadGroup, "main");
  227                   group = mainThreadGroup;
  228               } else {
  229                   group = mainThreadGroup;
  230               }
  231           }
  232   
  233           this.group = group;
  234           this.stackSize = stackSize;
  235           this.priority = priority;
  236           this.daemon = daemon;
  237           this.threadId = getNextThreadId();
  238           this.name = (name != null) ? name : THREAD + threadId; 
  239           // Each thread created from JNI has bootstrap class loader as
  240           // its context class loader. The only exception is the main thread
  241           // which has system class loader as its context class loader.
  242           this.contextClassLoader = contextLoader;
  243           this.target = null;
  244           // The thread is actually running.
  245           this.isAlive = true;
  246           this.started = true;
  247   
  248           ThreadWeakRef newRef = new ThreadWeakRef(this);
  249           newRef.setNativeAddr(nativeAddr);
  250   
  251           SecurityUtils.putContext(this, AccessController.getContext());
  252           // adding the thread to the thread group should be the last action
  253           group.add(this);
  254   
  255   	Thread parent = currentThread();
  256           if (parent != null && parent.inheritableValues != null) {
  257               inheritableValues = new ThreadLocal.Values(parent.inheritableValues);
  258           } 
  259   
  260       }
  261   
  262       /**
  263        * @com.intel.drl.spec_ref
  264        */
  265       public Thread(ThreadGroup group, Runnable target, String name,
  266                     long stackSize) {
  267   
  268           Thread currentThread = VMThreadManager.currentThread();
  269           SecurityManager securityManager = System.getSecurityManager();
  270           
  271           ThreadGroup threadGroup = null;
  272           if (group != null) {
  273               if (securityManager != null) {
  274                   securityManager.checkAccess(group);
  275               }
  276               threadGroup = group;
  277           } else if (securityManager != null) {
  278               threadGroup = securityManager.getThreadGroup();
  279           }
  280           if (threadGroup == null) {
  281               threadGroup = currentThread.group;
  282           }
  283   
  284           threadGroup.checkGroup();
  285   
  286           this.group = threadGroup;
  287           this.daemon = currentThread.daemon;
  288           this.contextClassLoader = currentThread.contextClassLoader;
  289           this.target = target;
  290           this.stackSize = stackSize;
  291           this.priority = currentThread.priority;
  292           this.threadId = getNextThreadId();
  293           // throws NullPointerException if the given name is null
  294           this.name = (name != THREAD) ? this.name = name.toString() :
  295               THREAD + threadId;
  296   
  297   
  298       
  299           checkGCWatermark();
  300           
  301           ThreadWeakRef oldRef = ThreadWeakRef.poll();
  302           ThreadWeakRef newRef = new ThreadWeakRef(this);
  303   
  304           long oldPointer = (oldRef == null) ? 0 : oldRef.getNativeAddr();
  305           long newPointer = VMThreadManager.init(this, newRef, oldPointer);
  306           if (newPointer == 0) {
  307               throw new OutOfMemoryError("Failed to create new thread");
  308           }
  309           newRef.setNativeAddr(newPointer);
  310   
  311           SecurityUtils.putContext(this, AccessController.getContext());
  312           checkAccess();
  313   
  314   	Thread parent = currentThread();
  315           if (parent != null && parent.inheritableValues != null) {
  316               inheritableValues = new ThreadLocal.Values(parent.inheritableValues);
  317           } 
  318   
  319       }
  320   
  321       /**
  322        * @com.intel.drl.spec_ref
  323        */
  324       public Thread(ThreadGroup group, String name) {
  325           this(group, null, name, 0);
  326       }
  327   
  328       /**
  329        * @com.intel.drl.spec_ref
  330        */
  331       public static int activeCount() {
  332           return currentThread().group.activeCount();
  333       }
  334   
  335       /**
  336        * @com.intel.drl.spec_ref
  337        */
  338       public static Thread currentThread() {
  339           return VMThreadManager.currentThread();
  340       }
  341   
  342       /**
  343        * @com.intel.drl.spec_ref
  344        */
  345       public static void dumpStack() {
  346           StackTraceElement[] stack = (new Throwable()).getStackTrace();
  347           System.err.println("Stack trace");
  348           for (int i = 0; i < stack.length; i++) {
  349               System.err.println(STACK_TRACE_INDENT + stack[i]);
  350           }
  351       }
  352   
  353       /**
  354        * @com.intel.drl.spec_ref
  355        */
  356       public static int enumerate(Thread[] list) {
  357           return currentThread().group.enumerate(list);
  358       }
  359   
  360       /**
  361        * @com.intel.drl.spec_ref
  362        */
  363       public static boolean holdsLock(Object object) {
  364           if (object == null) {
  365               throw new NullPointerException();
  366           }
  367           return VMThreadManager.holdsLock(object);
  368       }
  369   
  370       /**
  371        * @com.intel.drl.spec_ref
  372        */
  373       public static boolean interrupted() {
  374           return VMThreadManager.isInterrupted();
  375       }
  376   
  377       /**
  378        * @com.intel.drl.spec_ref
  379        */
  380       public static void sleep(long millis) throws InterruptedException {
  381           sleep(millis, 0);
  382       }
  383   
  384       /**
  385        * @com.intel.drl.spec_ref
  386        */
  387       public static void sleep(long millis, int nanos)
  388           throws InterruptedException {
  389           if (millis < 0 || nanos < 0 || nanos > 999999) {
  390               throw new IllegalArgumentException(
  391                   "Arguments don't match the expected range!");
  392           }
  393           int status = VMThreadManager.sleep(millis, nanos);
  394           if (status == VMThreadManager.TM_ERROR_INTERRUPT) {
  395               throw new InterruptedException();        
  396           } else if (status != VMThreadManager.TM_ERROR_NONE) {
  397               throw new InternalError(
  398                   "Thread Manager internal error " + status);
  399           }
  400       }
  401   
  402       /**
  403        * @com.intel.drl.spec_ref
  404        */
  405       public static void yield() {
  406           int status = VMThreadManager.yield();
  407           if (status != VMThreadManager.TM_ERROR_NONE) {
  408               throw new InternalError(
  409                   "Thread Manager internal error " + status);
  410           }
  411       }
  412   
  413       /**
  414        * @com.intel.drl.spec_ref
  415        */
  416       public final void checkAccess() {
  417           SecurityManager securityManager = System.getSecurityManager();
  418           if (securityManager != null) {
  419               securityManager.checkAccess(this);
  420           }
  421       }
  422   
  423       /**
  424        * @com.intel.drl.spec_ref
  425        * @deprecated
  426        */
  427       public int countStackFrames() {
  428           return 0; //deprecated
  429       }
  430   
  431       /**
  432        * @com.intel.drl.spec_ref
  433        * @deprecated
  434        */
  435       public void destroy() {
  436           // this method is not implemented
  437           throw new NoSuchMethodError();
  438       }
  439   
  440       /**
  441        * @com.intel.drl.spec_ref
  442        */
  443       public static Map<Thread, StackTraceElement[]> getAllStackTraces() {
  444           SecurityManager securityManager = System.getSecurityManager();
  445           if (securityManager != null) {
  446               securityManager
  447                   .checkPermission(RuntimePermissionCollection.GET_STACK_TRACE_PERMISSION);
  448               securityManager
  449                   .checkPermission(RuntimePermissionCollection.MODIFY_THREAD_GROUP_PERMISSION);
  450           }
  451           
  452           // find the initial ThreadGroup in the tree
  453           ThreadGroup parent = new ThreadGroup(currentThread().getThreadGroup(), "Temporary");
  454           ThreadGroup newParent = parent.getParent();
  455           parent.destroy();
  456           while (newParent != null) {
  457               parent = newParent;
  458               newParent = parent.getParent();
  459           }
  460           int threadsCount = parent.activeCount() + 1;
  461           int count;
  462           Thread[] liveThreads;
  463           while (true) {
  464               liveThreads = new Thread[threadsCount];
  465               count = parent.enumerate(liveThreads);
  466               if (count == threadsCount) {
  467                   threadsCount *= 2;
  468               } else {
  469                   break;
  470               }
  471           }
  472           Map<Thread, StackTraceElement[]> map = new HashMap<Thread, StackTraceElement[]>(count + 1);
  473           for (int i = 0; i < count; i++) {
  474               StackTraceElement[] ste = liveThreads[i].getStackTrace();
  475               if (ste.length != 0) {
  476                   map.put(liveThreads[i], ste);
  477               }
  478           }
  479           return map;
  480       }
  481   
  482       /**
  483        * @com.intel.drl.spec_ref
  484        */
  485       public ClassLoader getContextClassLoader() {
  486           synchronized (lock) {
  487               // First, if the conditions
  488               //    1) there is a security manager
  489               //    2) the caller's class loader is not null
  490               //    3) the caller's class loader is not the same as or an
  491               //    ancestor of contextClassLoader
  492               // are satisfied we should perform a security check.
  493               SecurityManager securityManager = System.getSecurityManager();
  494               if (securityManager != null) {
  495                   //the first condition is satisfied
  496                   ClassLoader callerClassLoader = VMClassRegistry
  497                       .getClassLoader(VMStack.getCallerClass(0));
  498                   if (callerClassLoader != null) {
  499                       //the second condition is satisfied
  500                       ClassLoader classLoader = contextClassLoader;
  501                       while (classLoader != null) {
  502                           if (classLoader == callerClassLoader) {
  503                               //the third condition is not satisfied
  504                               return contextClassLoader;
  505                           }
  506                           classLoader = classLoader.getParent();
  507                       }
  508                       //the third condition is satisfied
  509                       securityManager
  510                           .checkPermission(RuntimePermissionCollection.GET_CLASS_LOADER_PERMISSION);
  511                   }
  512               }
  513               return contextClassLoader;
  514           }
  515       }
  516   
  517       /**
  518        * @com.intel.drl.spec_ref
  519        */
  520       public final String getName() {
  521           return name;
  522       }
  523   
  524       /**
  525        * @com.intel.drl.spec_ref
  526        */
  527       public final int getPriority() {
  528           return priority;
  529       }
  530   
  531       /**
  532        * @com.intel.drl.spec_ref
  533        */
  534       public StackTraceElement[] getStackTrace() {
  535           if (currentThread() != this) {
  536               SecurityManager securityManager = System.getSecurityManager();
  537               if (securityManager != null) {
  538                   securityManager
  539                       .checkPermission(RuntimePermissionCollection.GET_STACK_TRACE_PERMISSION);
  540               }
  541           }
  542           StackTraceElement ste[] = VMStack.getThreadStackTrace(this);
  543           return ste != null ? ste : new StackTraceElement[0];
  544       }
  545       
  546       /**
  547        * @com.intel.drl.spec_ref
  548        */
  549       public final ThreadGroup getThreadGroup() {
  550           return group;
  551       }
  552   
  553       /**
  554        * @com.intel.drl.spec_ref
  555        */
  556       public long getId() {        
  557           return threadId;
  558       }
  559   
  560       /**
  561        * @com.intel.drl.spec_ref
  562        */
  563       public void interrupt() {
  564           synchronized (lock) {
  565               checkAccess();
  566               int status = VMThreadManager.interrupt(this);
  567               if (status != VMThreadManager.TM_ERROR_NONE) {
  568                   throw new InternalError(
  569                       "Thread Manager internal error " + status);
  570               }
  571           }
  572       }
  573   
  574       /**
  575        * @com.intel.drl.spec_ref
  576        */
  577       public final boolean isAlive() {
  578           synchronized (lock) {
  579               return this.isAlive;
  580           }
  581       }
  582   
  583   
  584       /**
  585        * @com.intel.drl.spec_ref
  586        */
  587       public final boolean isDaemon() {
  588           return daemon;
  589       }
  590   
  591       /**
  592        * @com.intel.drl.spec_ref
  593        */
  594       public boolean isInterrupted() {
  595           return VMThreadManager.isInterrupted(this);
  596       }
  597   
  598       /**
  599        * @com.intel.drl.spec_ref
  600        */
  601       public final synchronized void join() throws InterruptedException {
  602           while (isAlive()) {
  603               wait();
  604           }
  605       }
  606   
  607       /**
  608        * @com.intel.drl.spec_ref
  609        */
  610       public final synchronized void join(long millis) throws InterruptedException {
  611           if (millis == 0) {
  612               join();
  613           } else {
  614               long end = System.currentTimeMillis() + millis;
  615               while(isAlive()) {
  616                   wait(millis);
  617                   millis = end - System.currentTimeMillis();
  618                   if (millis <= 0) {
  619                      break;
  620                   }
  621               }
  622           }
  623       }
  624   
  625       /**
  626        * @com.intel.drl.spec_ref
  627        */
  628       public final synchronized void join(long millis, int nanos)
  629           throws InterruptedException {
  630           if (millis < 0 || nanos < 0 || nanos > 999999) {
  631               throw new IllegalArgumentException();
  632           } else if (millis == 0 && nanos == 0) {
  633               join();
  634           } else {
  635               long end = System.nanoTime() + 1000000*millis + (long)nanos;
  636               long rest;
  637               while (isAlive()) {
  638                   wait(millis, nanos);
  639                   rest = end - System.nanoTime();
  640                   if (rest <= 0)
  641                      break;
  642                   nanos  = (int)(rest % 1000000);
  643                   millis = rest / 1000000;
  644               }
  645           }
  646       }
  647   
  648       /**
  649        *  Note that this is unsnchronized - the assumption is that
  650        *  hythread does the synchronization for us
  651        *  
  652        * @com.intel.drl.spec_ref
  653        * @deprecated
  654        */
  655       public final void resume() {
  656               checkAccess();
  657               int status = VMThreadManager.resume(this);
  658               if (status != VMThreadManager.TM_ERROR_NONE) {
  659                   throw new InternalError(
  660                       "Thread Manager internal error " + status);
  661               }
  662       }
  663   
  664       /**
  665        * @com.intel.drl.spec_ref
  666        */
  667       public void run() {
  668           if (target != null) {
  669               target.run();
  670           }
  671       }
  672   
  673       void runImpl() {
  674           synchronized (lock) {
  675               this.isAlive = true;
  676               this.started = true;
  677               lock.notifyAll();
  678           }
  679   
  680           run();
  681       }
  682   
  683       /**
  684        * @com.intel.drl.spec_ref
  685        */
  686       public void setContextClassLoader(ClassLoader classLoader) {
  687           synchronized (lock) {
  688               SecurityManager securityManager = System.getSecurityManager();
  689               if (securityManager != null) {
  690                   securityManager
  691                       .checkPermission(RuntimePermissionCollection.SET_CONTEXT_CLASS_LOADER_PERMISSION);
  692               }
  693               contextClassLoader = classLoader;
  694           }
  695       }
  696   
  697       /**
  698        * @com.intel.drl.spec_ref We assume that 'active thread' means the same as
  699        *                         'alive thread'.
  700        */
  701       public final void setDaemon(boolean daemon) {
  702           synchronized (lock) {
  703               checkAccess();
  704               if (isAlive()) {
  705                   throw new IllegalThreadStateException();
  706               }
  707               this.daemon = daemon;
  708           }
  709       }
  710   
  711       /**
  712        * @com.intel.drl.spec_ref New name should not be <code>null</code>.
  713        * @throws NullPointerException if new name is <code>null</code>
  714        */
  715       public final void setName(String name) {
  716           checkAccess();
  717           // throws NullPointerException if the given name is null
  718           this.name = name.toString();
  719       }
  720   
  721       /**
  722        * @com.intel.drl.spec_ref
  723        */
  724       public final void setPriority(int priority) {
  725           checkAccess();
  726           if (priority > MAX_PRIORITY || priority < MIN_PRIORITY) {
  727               throw new IllegalArgumentException("Wrong Thread priority value");
  728           }
  729           ThreadGroup threadGroup = group;
  730           this.priority = (priority > threadGroup.maxPriority)
  731               ? threadGroup.maxPriority : priority;
  732           int status = VMThreadManager.setPriority(this, this.priority);
  733           if (status != VMThreadManager.TM_ERROR_NONE) {
  734               //throw new InternalError("Thread Manager internal error " + status);
  735           }
  736       }
  737   
  738       /**
  739        * @com.intel.drl.spec_ref
  740        */
  741       public synchronized void start() {
  742           synchronized (lock) {
  743               if (started) {
  744                   //this thread was started
  745                   throw new IllegalThreadStateException(
  746                           "This thread was already started!");
  747               }
  748   
  749               // adding the thread to the thread group
  750               group.add(this);
  751   
  752               
  753               if (VMThreadManager.start(this, stackSize, daemon, priority) != 0) {
  754                   throw new OutOfMemoryError("Failed to create new thread");
  755               } 
  756               
  757   
  758               // wjw -- why are we *waiting* for a child thread to actually start running?
  759               // this *guarantees* two context switches
  760               // nothing in j.l.Thread spec says we have to do this
  761               // my guess is that this actually masks an underlying race condition that we need to fix.
  762              
  763               boolean interrupted = false;
  764               while(!this.started) {
  765                   try {
  766                       lock.wait();
  767                   } catch (InterruptedException e) {
  768                       interrupted = true;
  769                   }
  770               }
  771   
  772               if (interrupted) {
  773                   Thread.currentThread().interrupt();
  774               }
  775           }
  776       }
  777   
  778       /**
  779        * Performs premortal actions. First it processes uncaught exception if any.
  780        * Second removes current thread from its thread group.
  781        * VM calls this method when current thread is detaching from VM.
  782        * 
  783        * @param uncaughtException uncaught exception or null
  784        */
  785       void detach(Throwable uncaughtException) {
  786           try {
  787               if (uncaughtException != null) {
  788                   getUncaughtExceptionHandler().uncaughtException(this, uncaughtException);
  789               }
  790           } finally {
  791               group.remove(this);
  792               synchronized(this) {
  793                   isAlive = false;
  794                   notifyAll();
  795               }
  796           }
  797       }
  798   
  799       public enum State {
  800           NEW,
  801           RUNNABLE,
  802           BLOCKED,
  803           WAITING,
  804           TIMED_WAITING,
  805           TERMINATED
  806       }
  807   
  808       /**
  809        * @com.intel.drl.spec_ref
  810        */
  811       public Thread.State  getState() {
  812   
  813   	boolean dead = false;
  814   	synchronized(lock) {
  815   		if(started && !isAlive() ) dead = true;
  816   	}
  817   	if (dead) return State.TERMINATED;
  818        
  819           int state = (VMThreadManager.getState(this));
  820   
  821           if (0 != (state & VMThreadManager.TM_THREAD_STATE_TERMINATED)) {         
  822               return State.TERMINATED;
  823           } else if  (0 != (state & VMThreadManager.TM_THREAD_STATE_WAITING_WITH_TIMEOUT)) {
  824               return State.TIMED_WAITING;
  825           } else if (0 != (state & VMThreadManager.TM_THREAD_STATE_WAITING) 
  826                   || 0 != (state & VMThreadManager.TM_THREAD_STATE_PARKED)) {
  827               return State.WAITING;
  828           } else if (0 != (state & VMThreadManager.TM_THREAD_STATE_BLOCKED_ON_MONITOR_ENTER)) {
  829               return State.BLOCKED;
  830   
  831           } else if (0 != (state & VMThreadManager.TM_THREAD_STATE_RUNNABLE)) {
  832               return State.RUNNABLE;
  833   
  834           //TODO track down all situations where a thread is really in RUNNABLE state 
  835           // but TM_THREAD_STATE_RUNNABLE is not set.  In the meantime, leave the following
  836           // TM_THREAD_STATE_ALIVE test as it is.
  837           } else if (0 != (state & VMThreadManager.TM_THREAD_STATE_ALIVE)) {
  838               return State.RUNNABLE;
  839           } else { 
  840               return State.NEW;  // by deduction, if its none of the above
  841           }
  842       }
  843   
  844       /**
  845        * @com.intel.drl.spec_ref
  846        * @deprecated
  847        */
  848       public final void stop() {
  849           synchronized (lock) {
  850           	if (isAlive()) {
  851                   stop(new ThreadDeath());
  852           	}
  853           }
  854       }
  855   
  856       /**
  857        * @com.intel.drl.spec_ref
  858        * @deprecated
  859        */
  860       public final void stop(Throwable throwable) {
  861           SecurityManager securityManager = System.getSecurityManager();
  862           if (securityManager != null) {
  863               securityManager.checkAccess(this);
  864               if (currentThread() != this || !(throwable instanceof ThreadDeath)) {
  865                   securityManager.checkPermission(
  866                       RuntimePermissionCollection.STOP_THREAD_PERMISSION);
  867               }
  868           }
  869           if (throwable == null) {
  870               throw new NullPointerException("The argument is null!");
  871           }
  872           synchronized (lock) {
  873               if (isAlive()) {
  874                   int status = VMThreadManager.stop(this, throwable);
  875                   if (status != VMThreadManager.TM_ERROR_NONE) {
  876                       throw new InternalError(
  877                           "Thread Manager internal error " + status);
  878                   }
  879               }
  880           }
  881       }
  882   
  883       /**
  884        *  Note that this is unsnchronized - the assumption is that
  885        *  hythread does the synchronization for us
  886        *  
  887        * @com.intel.drl.spec_ref
  888        * @deprecated
  889        */
  890       public final void suspend() {
  891           checkAccess();
  892   
  893           int status = VMThreadManager.suspend(this);
  894           if (status != VMThreadManager.TM_ERROR_NONE) {
  895               throw new InternalError("Thread Manager internal error " + status);
  896           }
  897       }
  898   
  899       /**
  900        * @com.intel.drl.spec_ref
  901        */
  902       public String toString() {
  903           ThreadGroup threadGroup = group;
  904           return "Thread[" + name + "," + priority + ","
  905               + ( (threadGroup == null) ? "" : threadGroup.name) + "]";
  906       }
  907   
  908       /**
  909        * @com.intel.drl.spec_ref
  910        */
  911       public static UncaughtExceptionHandler getDefaultUncaughtExceptionHandler() {
  912           return defaultExceptionHandler;
  913       }
  914   
  915       /**
  916        * @com.intel.drl.spec_ref
  917        */
  918       public static void setDefaultUncaughtExceptionHandler(UncaughtExceptionHandler eh) {
  919           SecurityManager sm = System.getSecurityManager();
  920           if (sm != null) {
  921               sm.checkPermission(RuntimePermissionCollection.SET_DEFAULT_UNCAUGHT_EXCEPTION_HANDLER_PERMISSION);
  922           }
  923           defaultExceptionHandler = eh;
  924       }
  925   
  926       /**
  927        * @com.intel.drl.spec_ref
  928        */
  929       public UncaughtExceptionHandler getUncaughtExceptionHandler() {
  930           if (exceptionHandler != null) {
  931               return exceptionHandler;
  932           }
  933           return getThreadGroup();
  934       }
  935   
  936       /**
  937        * @com.intel.drl.spec_ref
  938        */
  939       public void setUncaughtExceptionHandler(UncaughtExceptionHandler eh) {
  940           SecurityManager sm = System.getSecurityManager();
  941           if (sm != null) {
  942               sm.checkPermission(RuntimePermissionCollection.MODIFY_THREAD_PERMISSION);
  943           }
  944           exceptionHandler = eh;
  945       }
  946   
  947       /**
  948        * generates a unique thread ID
  949        */
  950       private static synchronized long getNextThreadId() 
  951       {
  952           return ++threadOrdinalNum;
  953       }
  954   
  955       /*
  956        * Checks if more then GC_WATERMARK_MAX_COUNT threads was created and calls
  957        * System.gc() to ensure that dead thread references was collected.
  958        */
  959       private void checkGCWatermark() 
  960       {
  961           if (++currentGCWatermarkCount % GC_WATERMARK_MAX_COUNT == 0) 
  962           {
  963               System.gc();
  964           }
  965       }
  966       
  967       /**
  968        * @com.intel.drl.spec_ref
  969        */
  970       public static interface UncaughtExceptionHandler 
  971       {
  972   
  973           /**
  974            * @com.intel.drl.spec_ref
  975            */
  976           void uncaughtException(Thread t, Throwable e);
  977       }
  978   }

Save This Page
Home » apache-harmony-6.0-src-r917296-snapshot » java » lang » [javadoc | source]