总结与使用

除初始线程组,其他的线程组都有父线程组

1.extends 和 implement

implements Thread.UncaughtExceptionHandler;
线程未捕获异常抛出候的处理类

2.构造方法

无参构造 ThreadGroup()

  1. private ThreadGroup() {
  2. this.name = "system";
  3. this.maxPriority = Thread.MAX_PRIORITY;
  4. this.parent = null;
  5. }

ThreadGroup(String)

  1. public ThreadGroup(String name) {
  2. this(Thread.currentThread().getThreadGroup(), name);
  3. }

ThreadGroup(ThreadGroup parent, String name)

  1. public ThreadGroup(ThreadGroup parent, String name) {
  2. this(checkParentAccess(parent), parent, name);
  3. }

ThreadGroup(Void unused, ThreadGroup parent, String name)

  1. // Void unused , 父线程组需要进行安全检查, Void 方法
  2. private ThreadGroup(Void unused, ThreadGroup parent, String name) {
  3. this.name = name;
  4. this.maxPriority = parent.maxPriority;
  5. this.daemon = parent.daemon;
  6. this.vmAllowSuspension = parent.vmAllowSuspension;
  7. this.parent = parent;
  8. parent.add(this);
  9. }


3.属性

【destroyed】: 是否被销毁

【daemon】: 是否守护线程组,守护线程组在线程组最后一个线程停止或者最后一个子线程组被移除时会自动销毁

【parent】:父线程组,final 修饰

【name】:线程组名称

【maxPriority】:线程组内最高优先级

【vmAllowSuspension】:vm是否允许中断

nUnstartedThreads】:未启动的线程数

nthreads】:线程组中的线程数

threads】:线程组中的线程

ngroups】:线程组数目

groups】:线程组中的子线程组

4.方法

native方法

Java方法

checkParentAccess(ThreadGroup)

检查当前线程是否有修改父线程组的权限

  1. private static Void checkParentAccess(ThreadGroup parent) {
  2. parent.checkAccess();
  3. return null;
  4. }

parentOf(ThreadGroup)

  1. public final boolean parentOf(ThreadGroup g) {
  2. for (; g != null ; g = g.parent) {
  3. if (g == this) {
  4. return true;
  5. }
  6. }
  7. return false;
  8. }

checkAccess(): 权限检查

activeCount():

查询线程组中的活动线程数量,返回的值并不准确,仅作为参考,线程组的线程时刻在变化。

  1. public int activeCount() {
  2. int result;
  3. int ngroupsSnapshot;
  4. //对当前线程组进行一个快照,然后再快照中统计活动线程
  5. ThreadGroup[] groupsSnapshot;
  6. synchronized (this) {
  7. if (destroyed) {
  8. return 0;
  9. }
  10. result = nthreads;
  11. ngroupsSnapshot = ngroups;
  12. if (groups != null) {
  13. groupsSnapshot = Arrays.copyOf(groups, ngroupsSnapshot);
  14. } else {
  15. groupsSnapshot = null;
  16. }
  17. }
  18. for (int i = 0 ; i < ngroupsSnapshot ; i++) {
  19. result += groupsSnapshot[i].activeCount();
  20. }
  21. return result;
  22. }

enumerate(Thread[] list,int n,boolean recurse):

将当前线程组的所有活动线程复制到list数组中,数组写满后停止,
n表示从list数组中的第n个位置开始写入线程。
recurse表示将当前线程组中的子线程组中线程也写入list。

  1. public int enumerate(Thread list[]) {
  2. checkAccess();
  3. return enumerate(list, 0, true);
  4. }
  5. public int enumerate(Thread list[], boolean recurse) {
  6. checkAccess();
  7. return enumerate(list, 0, recurse);
  8. }
  9. private int enumerate(Thread list[], int n, boolean recurse) {
  10. int ngroupsSnapshot = 0;
  11. ThreadGroup[] groupsSnapshot = null;
  12. synchronized (this) {
  13. //线程组已经被销毁,那么退出
  14. if (destroyed) {
  15. return 0;
  16. }
  17. //循环位置从n开始 如果n已经到了数组末尾,那么nt=0,不进入循环写数据
  18. int nt = nthreads;
  19. if (nt > list.length - n) {
  20. nt = list.length - n;
  21. }
  22. for (int i = 0; i < nt; i++) {
  23. //如果线程存活,写入list
  24. if (threads[i].isAlive()) {
  25. list[n++] = threads[i];
  26. }
  27. }
  28. //如果需要递归子线程组,那么写入子线程组快照
  29. if (recurse) {
  30. ngroupsSnapshot = ngroups;
  31. if (groups != null) {
  32. groupsSnapshot = Arrays.copyOf(groups, ngroupsSnapshot);
  33. } else {
  34. groupsSnapshot = null;
  35. }
  36. }
  37. }
  38. //将子线程组的数据递归写入list中
  39. if (recurse) {
  40. for (int i = 0 ; i < ngroupsSnapshot ; i++) {
  41. n = groupsSnapshot[i].enumerate(list, n, true);
  42. }
  43. }
  44. //返回list中
  45. return n;
  46. }

activeGroupCount():

存活的线程组数量,生成快照,从快照中统计存活的线程组数量

  1. public int activeGroupCount() {
  2. int ngroupsSnapshot;
  3. ThreadGroup[] groupsSnapshot;
  4. synchronized (this) {
  5. if (destroyed) {
  6. return 0;
  7. }
  8. ngroupsSnapshot = ngroups;
  9. if (groups != null) {
  10. groupsSnapshot = Arrays.copyOf(groups, ngroupsSnapshot);
  11. } else {
  12. groupsSnapshot = null;
  13. }
  14. }
  15. int n = ngroupsSnapshot;
  16. for (int i = 0 ; i < ngroupsSnapshot ; i++) {
  17. n += groupsSnapshot[i].activeGroupCount();
  18. }
  19. return n;
  20. }

enumerate(ThreadGroup list[],int n, boolean recurse)

参照Thread的enumerate方法

  1. public int enumerate(ThreadGroup list[]) {
  2. checkAccess();
  3. return enumerate(list, 0, true);
  4. }
  5. public int enumerate(ThreadGroup list[]) {
  6. checkAccess();
  7. return enumerate(list, 0, true);
  8. }
  9. private int enumerate(ThreadGroup list[], int n, boolean recurse) {
  10. int ngroupsSnapshot = 0;
  11. ThreadGroup[] groupsSnapshot = null;
  12. synchronized (this) {
  13. if (destroyed) {
  14. return 0;
  15. }
  16. int ng = ngroups;
  17. if (ng > list.length - n) {
  18. ng = list.length - n;
  19. }
  20. if (ng > 0) {
  21. System.arraycopy(groups, 0, list, n, ng);
  22. n += ng;
  23. }
  24. if (recurse) {
  25. ngroupsSnapshot = ngroups;
  26. if (groups != null) {
  27. groupsSnapshot = Arrays.copyOf(groups, ngroupsSnapshot);
  28. } else {
  29. groupsSnapshot = null;
  30. }
  31. }
  32. }
  33. if (recurse) {
  34. for (int i = 0 ; i < ngroupsSnapshot ; i++) {
  35. n = groupsSnapshot[i].enumerate(list, n, true);
  36. }
  37. }
  38. return n;
  39. }

stop(): Deprecated

停止线程组内的所有线程, 弃用原因是调用了线程的stop方法,参看Thread类的stop方法。

  1. @Deprecated
  2. public final void stop() {
  3. if (stopOrSuspend(false))
  4. Thread.currentThread().stop();
  5. }

suspend(): Deprecated

挂起线程组所有线程

  1. @Deprecated
  2. @SuppressWarnings("deprecation")
  3. public final void suspend() {
  4. if (stopOrSuspend(true))
  5. Thread.currentThread().suspend();
  6. }

stopOrSuspend(boolean suspend):

停止或者挂起 ,suspend false 表示停止所有线程,true表示挂起所有线程 , 停止的线程包括线程组子组里得所有线程,递归调用

  1. @SuppressWarnings("deprecation")
  2. private boolean stopOrSuspend(boolean suspend) {
  3. boolean suicide = false;
  4. Thread us = Thread.currentThread();
  5. int ngroupsSnapshot;
  6. ThreadGroup[] groupsSnapshot = null;
  7. synchronized (this) {
  8. checkAccess();
  9. for (int i = 0 ; i < nthreads ; i++) {
  10. if (threads[i]==us)
  11. suicide = true;
  12. else if (suspend)
  13. threads[i].suspend();
  14. else
  15. threads[i].stop();
  16. }
  17. ngroupsSnapshot = ngroups;
  18. if (groups != null) {
  19. groupsSnapshot = Arrays.copyOf(groups, ngroupsSnapshot);
  20. }
  21. }
  22. for (int i = 0 ; i < ngroupsSnapshot ; i++)
  23. suicide = groupsSnapshot[i].stopOrSuspend(suspend) || suicide;
  24. return suicide;
  25. }

interrupt():

中断线程组内的所有线程,递归调用,中断子线程组内的所有线程

  1. public final void interrupt() {
  2. int ngroupsSnapshot;
  3. ThreadGroup[] groupsSnapshot;
  4. synchronized (this) {
  5. checkAccess();
  6. for (int i = 0 ; i < nthreads ; i++) {
  7. threads[i].interrupt();
  8. }
  9. ngroupsSnapshot = ngroups;
  10. if (groups != null) {
  11. groupsSnapshot = Arrays.copyOf(groups, ngroupsSnapshot);
  12. } else {
  13. groupsSnapshot = null;
  14. }
  15. }
  16. for (int i = 0 ; i < ngroupsSnapshot ; i++) {
  17. groupsSnapshot[i].interrupt();
  18. }
  19. }

resume(): Deprecated

恢复所有的线程

  1. @Deprecated
  2. @SuppressWarnings("deprecation")
  3. public final void resume() {
  4. int ngroupsSnapshot;
  5. ThreadGroup[] groupsSnapshot;
  6. synchronized (this) {
  7. checkAccess();
  8. for (int i = 0 ; i < nthreads ; i++) {
  9. threads[i].resume();
  10. }
  11. ngroupsSnapshot = ngroups;
  12. if (groups != null) {
  13. groupsSnapshot = Arrays.copyOf(groups, ngroupsSnapshot);
  14. } else {
  15. groupsSnapshot = null;
  16. }
  17. }
  18. for (int i = 0 ; i < ngroupsSnapshot ; i++) {
  19. groupsSnapshot[i].resume();
  20. }
  21. }

destroy():

销毁线程组

  1. public final void destroy() {
  2. int ngroupsSnapshot;
  3. ThreadGroup[] groupsSnapshot;
  4. synchronized (this) {
  5. //权限检查
  6. checkAccess();
  7. //如果线程组已经被销毁,或者线程组还有线程
  8. if (destroyed || (nthreads > 0)) {
  9. throw new IllegalThreadStateException();
  10. }
  11. ngroupsSnapshot = ngroups;
  12. if (groups != null) {
  13. groupsSnapshot = Arrays.copyOf(groups, ngroupsSnapshot);
  14. } else {
  15. groupsSnapshot = null;
  16. }
  17. //为什么需要判断paraent!=null ,因为除了初始线程组外,其他线程组都有parent,也就是说,初始线程组是不能销毁的
  18. if (parent != null) {
  19. destroyed = true;
  20. ngroups = 0;
  21. groups = null;
  22. nthreads = 0;
  23. threads = null;
  24. }
  25. }
  26. for (int i = 0 ; i < ngroupsSnapshot ; i += 1) {
  27. groupsSnapshot[i].destroy();
  28. }
  29. //从父线程组移除当前的线程组
  30. if (parent != null) {
  31. parent.remove(this);
  32. }
  33. }

add(ThreadGroup g):

添加线程组到组内

  1. private final void add(ThreadGroup g){
  2. synchronized (this) {
  3. if (destroyed) {
  4. throw new IllegalThreadStateException();
  5. }
  6. if (groups == null) {
  7. groups = new ThreadGroup[4];
  8. } else if (ngroups == groups.length) {
  9. groups = Arrays.copyOf(groups, ngroups * 2);
  10. }
  11. groups[ngroups] = g;
  12. ngroups++;
  13. }
  14. }

remove(ThreadGroup g):

移除线程组

  1. private void remove(ThreadGroup g) {
  2. synchronized (this) {
  3. if (destroyed) {
  4. return;
  5. }
  6. for (int i = 0 ; i < ngroups ; i++) {
  7. if (groups[i] == g) {
  8. //如果线程组存在,那么移除该线程组,子线程组数组末尾置空
  9. ngroups -= 1;
  10. System.arraycopy(groups, i + 1, groups, i, ngroups - i);
  11. groups[ngroups] = null;
  12. break;
  13. }
  14. }
  15. //如果线程都停止,那么唤醒所有等待线程
  16. if (nthreads == 0) { notifyAll();}
  17. //如果是守护线程组, 那么需要检查是否还存活线程或者存有子线程组,如果没有那么就销毁线程组
  18. if (daemon && (nthreads == 0) &&(nUnstartedThreads == 0) && (ngroups == 0)){
  19. destroy();
  20. }
  21. }
  22. }

addUnstarted():

自增长未启动线程数量

  1. void addUnstarted() {
  2. synchronized(this) {
  3. if (destroyed) {
  4. throw new IllegalThreadStateException();
  5. }
  6. nUnstartedThreads++;
  7. }
  8. }

add(Thread t) :

添加线程到线程组中

  1. void add(Thread t) {
  2. synchronized (this) {
  3. if (destroyed) {
  4. throw new IllegalThreadStateException();
  5. }
  6. if (threads == null) {
  7. threads = new Thread[4];
  8. } else if (nthreads == threads.length) {
  9. threads = Arrays.copyOf(threads, nthreads * 2);
  10. }
  11. threads[nthreads] = t;
  12. nthreads++;
  13. nUnstartedThreads--;
  14. }
  15. }

threadStartFailed(Thread t):

线程启动失败通知

  1. void threadStartFailed(Thread t) {
  2. synchronized(this) {
  3. remove(t);
  4. nUnstartedThreads++;
  5. }
  6. }

threadTerminated(Thread t):

线程终止,通知

  1. void threadTerminated(Thread t) {
  2. synchronized (this) {
  3. remove(t);
  4. if (nthreads == 0) {
  5. notifyAll();
  6. }
  7. //如果是守护线程,需要检查,是否符合销毁线程组的条件
  8. if (daemon && (nthreads == 0) &&(nUnstartedThreads == 0) && (ngroups == 0)){
  9. destroy();
  10. }
  11. }
  12. }

remove():

移除线程组的线程

  1. private void remove(Thread t) {
  2. synchronized (this) {
  3. if (destroyed) {
  4. return;
  5. }
  6. for (int i = 0 ; i < nthreads ; i++) {
  7. if (threads[i] == t) {
  8. System.arraycopy(threads, i + 1, threads, i, --nthreads - i);
  9. threads[nthreads] = null;
  10. break;
  11. }
  12. }
  13. }
  14. }

list():

列举线程组成员

  1. void list(PrintStream out, int indent) {
  2. int ngroupsSnapshot;
  3. ThreadGroup[] groupsSnapshot;
  4. synchronized (this) {
  5. for (int j = 0 ; j < indent ; j++) {
  6. out.print(" ");
  7. }
  8. out.println(this);
  9. indent += 4;
  10. for (int i = 0 ; i < nthreads ; i++) {
  11. for (int j = 0 ; j < indent ; j++) {
  12. out.print(" ");
  13. }
  14. out.println(threads[i]);
  15. }
  16. ngroupsSnapshot = ngroups;
  17. if (groups != null) {
  18. groupsSnapshot = Arrays.copyOf(groups, ngroupsSnapshot);
  19. } else {
  20. groupsSnapshot = null;
  21. }
  22. }
  23. for (int i = 0 ; i < ngroupsSnapshot ; i++) {
  24. groupsSnapshot[i].list(out, indent);
  25. }
  26. }

uncaughtException(Thread t ,Throwable e):

线程组内线程异常未捕获时的处理方法

  1. public void uncaughtException(Thread t, Throwable e) {
  2. if (parent != null) {
  3. parent.uncaughtException(t, e);
  4. } else {
  5. Thread.UncaughtExceptionHandler ueh = Thread.getDefaultUncaughtExceptionHandler();
  6. if (ueh != null) {
  7. ueh.uncaughtException(t, e);
  8. } else if (!(e instanceof ThreadDeath)) {
  9. System.err.print("Exception in thread \""+ t.getName() + "\" ");
  10. e.printStackTrace(System.err);
  11. }
  12. }
  13. }

allowThreadSuspension(boolean b):

what is lowmem?

  1. @Deprecated
  2. public boolean allowThreadSuspension(boolean b) {
  3. this.vmAllowSuspension = b;
  4. if (!b) {
  5. VM.unsuspendSomeThreads();
  6. }
  7. return true;
  8. }

5.内部类