JavaSE-线程组浅析

        Java里的线程是可以归属到线程组中的,线程组中可以有线程,也可以有线程组,这种结构有点像树的形式。线程组可以批量化的管理线程或者线程对象,可以更好的组织线程。


线程对象关联线程组:一级关联

        一级关联的意思就是线程组中有子线程,但是不会在线程组中创建子线程组。在开发中经常用到这种模式,在创建一些零散的线程时,为了将它们有效的进行组织管理,我们会创建一个线程组,然后把这些零散的线程归属到这个线程组里。我先用一段代码来示例。

class ThreadA extends Thread{
    @Override
    public void run() {
        try{
            while(!Thread.currentThread().isInterrupted()){
                System.out.println("ThreadName = "+Thread.currentThread().getName()+"  所在的线程组是:"+Thread.currentThread().getThreadGroup().getName());
                Thread.sleep(1500);
            }
        }catch (InterruptedException i){
            i.printStackTrace();
        }
    }
}

class ThreadB extends Thread{
    @Override
    public void run() {
        try{
            while (!Thread.currentThread().isInterrupted()){
                System.out.println("ThreadName = "+Thread.currentThread().getName()+"  所在的线程组是:"+Thread.currentThread().getThreadGroup().getName());
                Thread.sleep(1500);
            }
        }catch (InterruptedException i){
            i.printStackTrace();
        }
    }
}


public class Main {
    public static void main(String[] args) {
        ThreadA threadA = new ThreadA();
        ThreadB threadB = new ThreadB();
        ThreadGroup group = new ThreadGroup("我的线程组");
        new Thread(group,threadA).start();
        new Thread(group,threadB).start();
        System.out.println("正在运行的线程数为 "+group.activeCount());
        System.out.println("正在运行的线程组为 "+group.getName());
    }
}

输出结果是:


         我们可以看出线程组中有两个线程,并且这两个线程只要不被终止就会一直打印信息。

        另外,线程必须在处于运行状态时才会受线程组的管理。


线程对象关联线程组:多级关联

扫描二维码关注公众号,回复: 759845 查看本文章

        多级关联的意思就是线程组中子线程组,子线程中还有子线程组。虽然这种情况在开发中不常见,因为线程树结构应该是越简单越好,如果结构过于复杂反而不利于线程对象的管理。JDK提供了多级关联的结构,我用代码示例一下。

public class Main{
    public static void main(String[] args){
        ThreadGroup mainGroup = Thread.currentThread().getThreadGroup();//获取main线程组
        ThreadGroup group = new ThreadGroup(mainGroup,"A");//创建新的线程组A,放在main线程组里
        Runnable runnable = ()->{//要放在线程组A中的线程
            try{
                System.out.println("New Thread's method");
                Thread.sleep(1500);
            }catch (InterruptedException i){
                i.printStackTrace();
            }
        };
        Thread NewThread = new Thread(group,runnable);
        NewThread.setName("New Thread");//创建新的线程并起名为Z
        NewThread.start();//线程必须启动才会被放到线程组里
        ThreadGroup[] threadGroups = new ThreadGroup[Thread.currentThread().getThreadGroup().activeGroupCount()];//创建ThreadGroup数组,用来存放main线程组中的子线程组
        Thread.currentThread().getThreadGroup().enumerate(threadGroups);//将当前线程中的子线程组(线程组A)以复制的形式放到上面创建的ThreadGroup数组中
        System.out.println("main线程中子线程组个数是: "+threadGroups.length+"   名字是:"+threadGroups[0].getName());//输出
        Thread[] listThread = new Thread[threadGroups[0].activeCount()];//和上面差不多,创建Thread数组,用来存放线程组A中的线程
        threadGroups[0].enumerate(listThread);//复制线程组A中的线程到Thread[]数组中
        System.out.println("线程组A中的线程名字是: "+listThread[0].getName());
    }
}

先看结果


        我先介绍几个方法

        activeGroupCount();取得当前线程组中的子线程组个数

        activeCount();取得当前线程组中子线程个数

        enumerate();将当前线程组中的子线程组/线程复制的方式拷贝到ThreadGroup[]/Thread[]中。

这段代码就是在main线程组里加了一个新线程组A,然后在子线程组A中增加了一个新的线程New_Thread。

线程组的自动归属

        如果我们新创建了一个线程组,但是并没有注明它被归属到哪个线程组里。那么该线程组的归属应该是什么呢?先看一段代码。

public class Main {
    public static void main(String[] args) {
        ThreadGroup maingroup = Thread.currentThread().getThreadGroup();//获得main线程组
        System.out.println("main线程组中的子线程组个数: "+maingroup.activeGroupCount());
        ThreadGroup threadGroup = new ThreadGroup("子线程组");
        System.out.println("main线程组中的子线程组个数: "+maingroup.activeGroupCount());
        ThreadGroup[] threadGroups = new ThreadGroup[maingroup.activeGroupCount()];//创建ThreadGroup数组,存放main线程组中的子线程组
        maingroup.enumerate(threadGroups);//将main线程组中的子线程组以复制的形式存放到ThreadGroup数组内
        System.out.println("子线程组的名字是; "+threadGroups[0].getName());//输出那个子线程组的名字
        System.out.println(threadGroup.getName()+"的父线程组的名字是:"+threadGroup.getParent());
    }
}

        这个例子说明在实例化一个ThreadGroup的时候,如果不指定归属的线程组,那么该线程组会被自动归属到当前线程对象所属的线程组中。上面的例子中的main线程组的子线程组个数由0变成了1,就是这个原因。


组内线程批量停止

        既然是线程组,那么我们可以批量的操作与管理组内的线程。

class MyThread extends Thread{
    public MyThread(ThreadGroup threadGroup, String name){
        super(threadGroup,name);
    }
    @Override
    public void run() {
        System.out.println("线程组:"+Thread.currentThread().getThreadGroup().getName()+"中的  "+Thread.currentThread().getName()+"  开始执行");
        while(!isInterrupted()){
            //无限死循环
        }
        System.out.println("线程组:"+Thread.currentThread().getThreadGroup().getName()+"中的  "+Thread.currentThread().getName()+"  结束了");
    }
}


public class Main{
    public static void main(String[] args){
        ThreadGroup my_group = new ThreadGroup("我的线程组");
        for(int i = 1;i<=5;i++) {
            new MyThread(my_group, "线程" + i).start();//创建新的线程,放到线程组中。
        }//启动所有线程
        try {
            Thread.sleep(3000);
        }catch (InterruptedException i){
            i.printStackTrace();
        }
        my_group.interrupt();
    }
}


        首先创建一个线程组,然后在组中启动五个线程,让它们进入死循环。当我们调用了ThreadGroup中的interrupt()方法时,相当于给线程组中每个线程都调用了interrupt()方法,所以isInterrupted()方法返回false,五个线程批量停止。当然,除了停止之外我们还可以调用ThreadGroup中的其他方法批量管理子线程。这只是个例子罢了。


        有关线程组的概念就总结到这里,希望对大家能有所帮助。


猜你喜欢

转载自blog.csdn.net/qq_38449518/article/details/80203601