java threadgourp_多线程-ThreadGroup详细讲解

默认情况下, 新的线程都会被加入到main线程所在的group中, main线程的group名字同线程名。 如同线程存在父子关系一样,ThreadGroup同样也存在父子关系。

创建ThreadGroup

public ThreadGroup(String name)public ThreadGroup(ThreadGroup parent, String nmae)

public class ThreadGroupCreator {

public static void main(String[] args) {

// 获取当前线程的ThreadGroup

ThreadGroup currentGroup = Thread.currentThread().getThreadGroup();

// 定义一个新的group

ThreadGroup group1 = new ThreadGroup("Group1");

// 输出为true

System.out.println(group1 == currentGroup);

// 定义group2, 指定group1为其父group

ThreadGroup group2 = new ThreadGroup(group1,"group2");

// 输出为true

System.out.println(group2.getParent() == group1);

}

}

复制Thread数组

ThreadGroup中的两个方法

public int enumerate(Thread[] list)public int enumerate(Thread[] list, boolean recurse)

上面两个方法,会将ThreadGroup中的active线程全部复制到Thread数组中,其中recurse参数如果为true,则该方法会将所以子group中的active线程都递归到Thread数组中。enumerate(Thread[] list)实际上等价于enumerate(Thread[] list, true)。

public class ThreadGroupEnumerateThreads {

public static void main(String[] args) throws InterruptedException {

// 创建一个ThreadGroup

ThreadGroup myGroup = new ThreadGroup("MyGroup");

// 创建线程传入threadGroup

Thread thread = new Thread(myGroup, () -> {

try {

TimeUnit.SECONDS.sleep(10);

} catch (InterruptedException e) {

e.printStackTrace();

}

}, "MyThread");

thread.start();

TimeUnit.MILLISECONDS.sleep(2);

ThreadGroup mainGroup = Thread.currentThread().getThreadGroup();

Thread[] list = new Thread[mainGroup.activeCount()];

int recurseSize = mainGroup.enumerate(list);

System.out.println(recurseSize);

recurseSize = mainGroup.enumerate(list, false);

System.out.println(recurseSize);

}

}

上面代码运行之后,最后一个输出会比第一个小1, 那是因为代码中将递归recurse设置为了false, MyGroup中的线程将不会包含在内。

复制ThreadGroup数组

ThreadGroup中的两个方法

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

public class ThreadGroupEnumerateThreadGroups {

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.activeGroupCount()];

int recurseSize = mainGroup.enumerate(list);

System.out.println(recurseSize);

recurseSize = mainGroup.enumerate(list, false);

System.out.println(recurseSize);

}

}

myGroup1的匀group为mainGroup, 而myGroup2的父group为myGroup1, 因此上述的代码运行之后,递归复制的结果为2, 不递归的情况下为1 。

ThreadGroup操作

activeCount() 获取group中活跃的线程activeGroupCount() 获取group中活跃的子groupgetMaxPriority() 获取group的优先级getName 获取group的名字getParent() 获取group的父grouplist() 该方法没有返回值, 执行该方法会将group中所有活跃的线程信息打印到控制台parentOf(ThreadGroup g) 判断当前group是不是给定group的父groupsetMaxPriority(int pri) 设置group的最大优先级, 最大优先级不能超过父group的最大优先级, 执行该方法不仅会改变当前group的最大优先级, 还会改变所有子group的最大优先级。

public class ThreadGroupBasic {

public static void main(String[] args) throws InterruptedException {

ThreadGroup group = new ThreadGroup("group1");

Thread thread = new Thread(group, ()-> {

try {

TimeUnit.SECONDS.sleep(1);

} catch (InterruptedException e) {

e.printStackTrace();

}

});

thread.setDaemon(true);

thread.start();

TimeUnit.MILLISECONDS.sleep(1);

ThreadGroup mainGroup = Thread.currentThread().getThreadGroup();

System.out.println("activeCount=" + mainGroup.activeCount());

System.out.println("activeGroupCount="+ mainGroup.activeGroupCount());

System.out.println("getMaxPriority=" + mainGroup.getMaxPriority());

System.out.println("getName=" + mainGroup.getName());

System.out.println("getParent=" + mainGroup.getParent());

mainGroup.list();

System.out.println("---------------");

System.out.println("partOf=" + mainGroup.parentOf(group));

System.out.println("parentOf=" + mainGroup.parentOf(mainGroup));

}

}

如果把一个高优先级的线程,加入一个线程组以后, 再改变组的优先级小于线程的优先级,会怎样?

import java.util.concurrent.TimeUnit;

public class ThreadGroupPriority {

public static void main(String[] args) {

ThreadGroup group = new ThreadGroup("group1");

Thread thread = new Thread(group, ()->{

try {

TimeUnit.SECONDS.sleep(1);

} catch (InterruptedException e) {

e.printStackTrace();

}

}, "thread");

thread.setDaemon(true);

thread.start();

System.out.println("group.getMaxPriority()" + group.getMaxPriority());

System.out.println("thread.getPriority()" + thread.getPriority());

// 改变group的最大值

group.setMaxPriority(3);

System.out.println("group.getMaxPriority()" + group.getMaxPriority());

System.out.println("thread.getPriority()" + thread.getPriority());

}

}

打印

group.getMaxPriority()10

thread.getPriority()5

group.getMaxPriority()3

thread.getPriority()5

Process finished with exit code 0

改低组的最大优先组后, 已加入的线程的优先级不变, 后面加入的线程不会大于组的优先级

ThreadGroup的interrupt

interrupt一个group会导致该group中所有active线程都被interrupt, 也就是说该group中每一个线程的interrupt标识都被设置了。

import java.util.concurrent.TimeUnit;

public class ThreadGroupInterrupt {

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) {

break;

}

}

System.out.println("t1 will exit");

}, "t1").start();

new Thread(group, () -> {

while (true) {

try {

TimeUnit.MILLISECONDS.sleep(1);

} catch (InterruptedException e) {

break;

}

}

System.out.println("t2 will exit");

}, "t2").start();

TimeUnit.MILLISECONDS.sleep(2);

group.interrupt();

}

}

打印

t2 will exit

t1 will exit

ThreadGroup的destroy

destroy用于销毁ThreadGroup, 该方法只是针对一个没有任何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();

}

}

打印

group.isDestroyed=false

java.lang.ThreadGroup[name=main,maxpri=10]

Thread[main,5,main]

Thread[Monitor Ctrl-Break,5,main]

java.lang.ThreadGroup[name=TestGroup,maxpri=10]

group.isDestroyed=true

java.lang.ThreadGroup[name=main,maxpri=10]

Thread[main,5,main]

Thread[Monitor Ctrl-Break,5,main]

守护ThreadGroup

线程可以设置为守护线程, ThreadGroup也可以设为守护ThreadGroup, 但是若将一个ThreadGroup设置为daemon, 也并不会影响线程的daemon属性, 如果一个ThreadGroup的daemon被设置为true, 那么在group中没有任何active线程的时候该group将自动destroy

import java.util.concurrent.TimeUnit;

public class ThreadGroupDaemon {

public static void main(String[] args) throws InterruptedException {

ThreadGroup group1 = new ThreadGroup("Group1");

new Thread(group1, () -> {

try {

TimeUnit.SECONDS.sleep(1);

} catch (InterruptedException e) {

e.printStackTrace();

}

}, "group1-thread").start();

ThreadGroup group2 = new ThreadGroup("Group2");

new Thread(group2, () -> {

try {

TimeUnit.SECONDS.sleep(1);

} catch (InterruptedException e) {

e.printStackTrace();

}

}, "group2-thread2").start();

group2.setDaemon(true);

TimeUnit.SECONDS.sleep(3);

System.out.println(group1.isDestroyed());

System.out.println(group2.isDestroyed());

}

}

打印

false

true

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值