853 854 /** 855 * Increments the count of unstarted threads in the thread group. 856 * Unstarted threads are not added to the thread group so that they 857 * can be collected if they are never started, but they must be 858 * counted so that daemon thread groups with unstarted threads in 859 * them are not destroyed. 860 */ 861 void addUnstarted() { 862 synchronized(this) { 863 if (destroyed) { 864 throw new IllegalThreadStateException(); 865 } 866 nUnstartedThreads++; 867 } 868 } 869 870 /** 871 * Notifies the group that the thread {@code t} is about to be 872 * started and adds the thread to this thread group. 873 */ 874 void threadStarting(Thread t) { 875 add(t); 876 } 877 878 /** 879 * Adds the specified thread to this thread group. 880 * 881 * <p> Note: This method is called from both library code 882 * and the Virtual Machine. It is called from VM to add 883 * certain system threads to the system thread group. 884 * 885 * @param t 886 * the Thread to be added 887 * 888 * @throws IllegalThreadStateException 889 * if the Thread group has been destroyed 890 */ 891 void add(Thread t) { 892 synchronized (this) { 893 if (destroyed) { 894 throw new IllegalThreadStateException(); 895 } 896 if (threads == null) { 897 threads = new Thread[4]; 898 } else if (nthreads == threads.length) { 899 threads = Arrays.copyOf(threads, nthreads * 2); 900 } 901 threads[nthreads] = t; 902 903 // This is done last so it doesn't matter in case the 904 // thread is killed 905 nthreads++; 906 } 907 } 908 909 /** 910 * Notifies the group that the thread {@code t} has completed 911 * an attempt to start. 912 * 913 * <p> If the thread has been started successfully 914 * then the group has its unstarted Threads count decremented. 915 * Otherwise the state of this thread group is rolled back as if the 916 * attempt to start the thread has never occurred. The thread is again 917 * considered an unstarted member of the thread group, and a subsequent 918 * attempt to start the thread is permitted. 919 * 920 * @param t 921 * the Thread whose start method was invoked 922 * 923 * @param failed 924 * true if the thread could not be started successfully 925 */ 926 void threadStarted(Thread t, boolean failed) { 927 synchronized(this) { 928 if (failed) { 929 remove(t); 930 } else { 931 if (destroyed) { 932 return; 933 } 934 nUnstartedThreads--; 935 } 936 } 937 } 938 939 /** 940 * Notifies the group that the thread {@code t} has terminated. 941 * 942 * <p> Destroy the group if all of the following conditions are 943 * true: this is a daemon thread group; there are no more alive 944 * or unstarted threads in the group; there are no subgroups in 945 * this thread group. 946 * 947 * @param t 948 * the Thread that has terminated 949 */ 950 void threadTerminated(Thread t) { 951 synchronized (this) { 952 remove(t); 953 954 if (nthreads == 0) { 955 notifyAll(); 956 } 957 if (daemon && (nthreads == 0) && | 853 854 /** 855 * Increments the count of unstarted threads in the thread group. 856 * Unstarted threads are not added to the thread group so that they 857 * can be collected if they are never started, but they must be 858 * counted so that daemon thread groups with unstarted threads in 859 * them are not destroyed. 860 */ 861 void addUnstarted() { 862 synchronized(this) { 863 if (destroyed) { 864 throw new IllegalThreadStateException(); 865 } 866 nUnstartedThreads++; 867 } 868 } 869 870 /** 871 * Notifies the group that the thread {@code t} is about to be 872 * started and adds the thread to this thread group. 873 * 874 * The thread is now a fully fledged member of the group, even though 875 * it hasn't been started yet. It will prevent the group from being 876 * destroyed so the unstarted Threads count is decremented. 877 */ 878 void threadStarting(Thread t) { 879 synchronized (this) { 880 add(t); 881 nUnstartedThreads--; 882 } 883 } 884 885 /** 886 * Adds the specified thread to this thread group. 887 * 888 * <p> Note: This method is called from both library code 889 * and the Virtual Machine. It is called from VM to add 890 * certain system threads to the system thread group. 891 * 892 * @param t 893 * the Thread to be added 894 * 895 * @throws IllegalThreadStateException 896 * if the Thread group has been destroyed 897 */ 898 void add(Thread t) { 899 synchronized (this) { 900 if (destroyed) { 901 throw new IllegalThreadStateException(); 902 } 903 if (threads == null) { 904 threads = new Thread[4]; 905 } else if (nthreads == threads.length) { 906 threads = Arrays.copyOf(threads, nthreads * 2); 907 } 908 threads[nthreads] = t; 909 910 // This is done last so it doesn't matter in case the 911 // thread is killed 912 nthreads++; 913 } 914 } 915 916 /** 917 * Notifies the group that the thread {@code t} has failed 918 * an attempt to start. 919 * 920 * <p> The state of this thread group is rolled back as if the 921 * attempt to start the thread has never occurred. The thread is again 922 * considered an unstarted member of the thread group, and a subsequent 923 * attempt to start the thread is permitted. 924 * 925 * @param t 926 * the Thread whose start method was invoked 927 * 928 * @param failed 929 * true if the thread could not be started successfully 930 */ 931 void threadStartFailed(Thread t) { 932 synchronized(this) { 933 remove(t); 934 nUnstartedThreads++; 935 } 936 } 937 938 /** 939 * Notifies the group that the thread {@code t} has terminated. 940 * 941 * <p> Destroy the group if all of the following conditions are 942 * true: this is a daemon thread group; there are no more alive 943 * or unstarted threads in the group; there are no subgroups in 944 * this thread group. 945 * 946 * @param t 947 * the Thread that has terminated 948 */ 949 void threadTerminated(Thread t) { 950 synchronized (this) { 951 remove(t); 952 953 if (nthreads == 0) { 954 notifyAll(); 955 } 956 if (daemon && (nthreads == 0) && |