网站修改联系方式,网站建设裕鸿国际,江苏做网站价格,怎么做自动下单网站1.ThreadGroup 与 Thread 在Java程序中#xff0c; 默认情况下#xff0c; 新的线程都会被加入到main线程所在的group中#xff0c; main线程的group名字同线程名。如同线程存在父子关系一样#xff0c; Thread Group同样也存在父子关系。图6-1就很好地说明了父子thread、父…1.ThreadGroup 与 Thread 在Java程序中 默认情况下 新的线程都会被加入到main线程所在的group中 main线程的group名字同线程名。如同线程存在父子关系一样 Thread Group同样也存在父子关系。图6-1就很好地说明了父子thread、父子thread Group以及thread和group之间的层次关系 2.创建ThreadGroup 
创建Thread Group的语法如下 
public Thread Group(String name)
public Thread Group(Thread Group parent String name) 
创建Thread Group的语法非常简单 可通过上面某个构造函数来创建 第一个构造函数为Thread Group赋予了名字 但是该Thread Group的父Thread Group是创建它的线程所在的Thread Group 第二个Thread Group的构造函数赋予group名字的同时又显式地指定了父Group。 public class TestThreadGroup {public static void main(String[] args) {ThreadGroup currentGroup  Thread.currentThread().getThreadGroup();ThreadGroup group1  new ThreadGroup(group1);System.out.println(group1.getParent()  currentGroup);ThreadGroup group2  new ThreadGroup(group1, Group2);System.out.println(group2.getParent()  group1);}
} 
3.复制Thread数组和ThreadGroup数组 
3,1复制Thread数组 
public int enumerate(Thread[] list);
public int enumerate(Thread[] list boolean recurse); 
上述两个方法 会将Thread Group中的active线程全部复制到Thread数组中 其中recurse参数如果为true 则该方法会将所有子group中的active线程都递归到Thread数组中 enumerate(Thread[] list) 实际上等价于enumerate(Thread[] true)  上面两个方法都调用了Thread Group的私有方法enumerate private int enumerate(Thread list[], int n, boolean recurse) {int ngroupsSnapshot  0;ThreadGroup[] groupsSnapshot  null;synchronized (this) {if (destroyed) {return 0;}int nt  nthreads;if (nt  list.length - n) {nt  list.length - n;}for (int i  0; i  nt; i) {if (threads[i].isAlive()) {list[n]  threads[i];}}if (recurse) {ngroupsSnapshot  ngroups;if (groups ! null) {groupsSnapshot  Arrays.copyOf(groups, ngroupsSnapshot);} else {groupsSnapshot  null;}}}if (recurse) {for (int i  0 ; i  ngroupsSnapshot ; i) {n  groupsSnapshot[i].enumerate(list, n, true);}}return n;} 
举一例enumerate方法的使用 
import java.util.concurrent.TimeUnit;public class TestThreadGroup {public static void main(String[] args) throws InterruptedException {ThreadGroup myGroup  new ThreadGroup(mygroup);Thread th   new Thread(myGroup,()- {while(true) {try {TimeUnit.SECONDS.sleep(1);} catch (InterruptedException e) {e.printStackTrace();}}},MyThread);th.start();TimeUnit.MILLISECONDS.sleep(2);ThreadGroup mainGroup  Thread.currentThread().getThreadGroup();Thread[] list  new Thread[mainGroup.activeCount()];int recuseSize  mainGroup.enumerate(list);System.out.println(recuseSize);recuseSize  mainGroup.enumerate(list,false);System.out.println(recuseSize);}
} 
上面的代码运行之后 最后一个输出会比第一个少1 那是因为代码中将递归recurse设置为了false my Group中的线程将不会包含在内。 
3.2 复制ThreadGroup数组 
public int enumerate(Thread Group[] list);
public int enumerate(Thread Group[] list boolean recurse); 
和复制Thread数组类似 上述两个方法 主要用于复制当前Thread Group的子Group同样recurse会决定是否以递归的方式复制。 import java.util.concurrent.TimeUnit;public class TestCopyThreadGroup {public static void main(String[] args) throws InterruptedException {ThreadGroup myGroup1  new ThreadGroup(MyGroup1);ThreadGroup myGroup2  new ThreadGroup(myGroup1, MyGroup2);TimeUnit.MILLISECONDS.sleep(2);ThreadGroup mainGroup  Thread.currentThread().getThreadGroup();ThreadGroup[] list  new ThreadGroup[mainGroup.activeCount()];int recurseSize  mainGroup.enumerate(list);System.out.println(recurseSize);recurseSize  mainGroup.enumerate(list,false);System.out.println(recurseSize);}
} 在代码清单6-3中 my Group 1的父group为main Group 而my Group 2的父group为my Group 1 因此上述的代码运行之后 递归复制的结果为2 不递归的情况下为1。 4.ThreadGroup操作 
4.1ThreadGroup的基本操作 
import java.util.concurrent.TimeUnit;public class ThreadGroupBasic {public static void main(String[] args) {ThreadGroup group  new ThreadGroup(group1);Thread thread  new Thread(group,() - {while(true) {try {TimeUnit.SECONDS.sleep(1);} catch (InterruptedException e) {e.printStackTrace();}}}, thread);thread.setDaemon(true);thread.start();ThreadGroup mainGroup  Thread.currentThread().getThreadGroup();System.out.println(activeCount  mainGroup.activeCount());System.out.println(activeGroupCount  mainGroup.activeGroupCount());mainGroup.list();System.out.println(--------------------------);System.out.println(parentOf  mainGroup.parentOf(group));}
} 
activeCount() 用于获取group中活跃的线程 这只是个估计值 并不能百分之百地保证数字一定正确 原因前面已经分析过 该方法会递归获取其他子group中的活跃线程。activeGroupCount() 用于获取group中活跃的子group 这也是一个近似估值 该方法也会递归获取所有的子group。getMaxPriority() 用于获取group的优先级默认情况下Group的优先级为10在该group中 所有线程的优先级都不能大于group的优先级。getName() 用于获取group的名字。getParent() 用于获取group的父group 如果父group不存在 则会返回null 比如system group的父group就为null。list() 该方法没有返回值 执行该方法会将group中所有的活跃线程信息全部输出到控制台 也就是System.out。parentOf(Thread Group g) 会判断当前group是不是给定group的父group 另外如果给定的group就是自己本身那么该方法也会返回true。setMaxPriority(int pri) 会指定group的最大优先级 最大优先级不能超过父group的最大优先级 执行该方法不仅会改变当前group的最大优先级 还会改变所有子group的最大优先级 4.2 ThreadGroup的interrupt 
interrupt一个thread group会导致该group中所有的active线程都被interrupt 也就是说该group中每一个线程的interrupt标识都被设置了 下面是Thread Group interrupt方法的源码   
public final void interrupt() {int ngroupsSnapshot;ThreadGroup[] groupsSnapshot;synchronized (this) {checkAccess();for (int i  0 ; i  nthreads ; i) {threads[i].interrupt();}ngroupsSnapshot  ngroups;if (groups ! null) {groupsSnapshot  Arrays.copyOf(groups, ngroupsSnapshot);} else {groupsSnapshot  null;}}for (int i  0 ; i  ngroupsSnapshot ; i) {groupsSnapshot[i].interrupt();}} 
interrupt方法案例 import java.util.concurrent.TimeUnit;public class TestThreadInterrupt {public static void main(String[] args) throws InterruptedException {ThreadGroup group  new ThreadGroup(TestGroup);new Thread(group,() - {while(true) {try {TimeUnit.MILLISECONDS.sleep(2);} catch (InterruptedException e) {e.printStackTrace();}}},t1).start();new Thread(group,()- {try {TimeUnit.MILLISECONDS.sleep(1);} catch (InterruptedException e) {e.printStackTrace();}},t2).start();TimeUnit.MILLISECONDS.sleep(2);group.interrupt();}
} 
4.3ThreadGroup的destroy 
destroy用于销毁Thread Group 该方法只是针对一个没有任何active线程的group进行一次destroy标记 调用该方法的直接结果是在父group中将自己移除 public class ThreadGroupDestroy {public static void main(String[] args) {ThreadGroup group  new ThreadGroup(TestGroup);ThreadGroup mainGroup  Thread.currentThread().getThreadGroup();System.out.println(group.isDestroyed  group.isDestroyed());mainGroup.list();group.destroy();System.out.println(group.isDestroyed  group.isDestroyed());mainGroup.list();}
} 4.4守护ThreadGroup 
线程可以设置为守护线程 Thread Group也可以设置为守护Thread Group 但是若将一个Thread Group设置为daemon 也并不会影响线程的daemon属性 如果一个Thread Group的daemon被设置为true 那么在group中没有任何active线程的时候该group将自动destroy 下面我们给出一个简单的例子来对其进行说明 import java.util.concurrent.TimeUnit;public class ThreadGroupDaemon {public static void main(String[] args) throws InterruptedException {ThreadGroup group  new ThreadGroup(Group1);new Thread(group,()- {try {TimeUnit.SECONDS.sleep(1);} catch (InterruptedException e) {e.printStackTrace();}},group1-thread1).start();ThreadGroup group2  new ThreadGroup(Group2);new Thread(group2,()- {try {TimeUnit.SECONDS.sleep(1);} catch (InterruptedException e) {e.printStackTrace();}},group2-thread1).start();group2.setDaemon(true);TimeUnit.SECONDS.sleep(3);System.out.println(group.isDestroyed());System.out.println(group2.isDestroyed());}
} 
在上面的代码中 第二个group的daemon被设置为true 当其中没有active线程的时候 该group将会自动被destroy 而第一个group则相反。