java ThreadGroup线程分组
是什么?为什么?怎么做?
一、是什么
线程组(ThreadGroup)就是由线程组成的管理线程的类,这个类是java.lang.ThreadGroup类。
二、为什么
有时候往往会存在一些线程做同样的任务,如果想对其进行统一管理,那么就可以把这些线程设置成同一个线程组。在线程组内,无论多少线程还在运行,他们的状态可以被一个call中断。
我个人认为:把任务相同的线程划分为同一线程组,可以更好地区分各个线程模块所负责的功能,并且提供管理。比如说我要完成一个功能,可能需要开10条线程,如果其中一条线程完成了任务(线程结束了),那么我需要停止剩下的9条线程。在这种场景下,如果不使用线程组,我可能需要把剩下的线程逐一停止。但是如果有线程组,我可以直接命令整个线程组停止工作,这样就直接把剩下的线程都停了。
三、怎么做
设计一个需求,现存在三条线程,我想让这三条线程交替执行,直到num=0为止,代码大概是这样:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
package testGroup; public class newtest { public static void main(String[] args) { task task = new task(); Thread thread1 = new Thread(task); Thread thread2 = new Thread(task); Thread thread3 = new Thread(task); thread1.start(); thread2.start(); thread3.start(); } } class task implements Runnable { private volatile int num = 50; private synchronized int getNum() { return num--; } public void run() { // TODO Auto-generated method stub System.out.println(Thread.currentThread().getName() + " start"); int output; while (!Thread.currentThread().isInterrupted()) { if ((output = getNum()) > 0) { System.out.println(Thread.currentThread().getName() + ":" + output); try { Thread.sleep(1000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } }else { break; } } System.out.println(Thread.currentThread().getName() + " end"); } } |
这三条线程的任务都是一样的,所以可以将其设置为同一线程组:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 |
package testGroup; public class newtest { public static void main(String[] args) { ThreadGroup threadGroup = new ThreadGroup("tasks"); task task = new task(); Thread thread1 = new Thread(threadGroup, task); Thread thread2 = new Thread(threadGroup, task); Thread thread3 = new Thread(threadGroup, task); thread1.start(); thread2.start(); thread3.start(); System.out.println("tasks:" + threadGroup.activeCount()); // thread1.interrupt(); // thread2.interrupt(); // thread3.interrupt(); threadGroup.interrupt(); } } class task implements Runnable { private volatile int num = 50; private synchronized int getNum() { return num--; } public void run() { // TODO Auto-generated method stub System.out.println(Thread.currentThread().getName() + " start"); int output; while (!Thread.currentThread().isInterrupted()) { if ((output = getNum()) > 0) { System.out.println(Thread.currentThread().getName() + ":" + output); try { Thread.sleep(1000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); break; } } else { break; } } System.out.println(Thread.currentThread().getName() + " end"); } } |
这里设置了一个线程组:
1 |
ThreadGroup threadGroup = new ThreadGroup("tasks"); |
如果要interrupt所有线程,不需要逐个interrupt,对整个线程组interrupt就好了。
1 2 3 4 5 |
// thread1.interrupt(); // thread2.interrupt(); // thread3.interrupt(); threadGroup.interrupt(); |
如果某一条线程结束了,那么说明num已经为0了,那么我想要interrupt其他线程,让他们提前结束(这个情景应该挺多的)。可以这样实现:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
package testGroup; public class newtest { public static void main(String[] args) { ThreadGroup threadGroup = new ThreadGroup("tasks"); task task = new task(); Thread thread1 = new Thread(threadGroup, task); Thread thread2 = new Thread(threadGroup, task); Thread thread3 = new Thread(threadGroup, task); thread1.start(); thread2.start(); thread3.start(); // thread1.interrupt(); // thread2.interrupt(); // thread3.interrupt(); while (true) { if (threadGroup.activeCount() < 3) { threadGroup.interrupt(); System.out.println("finished"); break; } } } } |
一旦threadGroup.activeCount() < 3,那就是说当前线程组中已经有一条线程完成任务了,那么我可以interrupt整个线程组,停止剩下的任务。
(其实这个功能可以这样实现:把所有线程放到数组中,while循环检测所有线程是否alive,如果有线程结束了,那么interrupt整个数组中的线程)
除此之外,线程组还有一些功能可以发掘,这里就不深入了。
四、总结
线程组方便了我们对执行相同任务的线程的管理。一些情景中可以尝试使用。