码迷,mamicode.com
首页 > 编程语言 > 详细

Java多线程编程7--拾遗增补--线程组

时间:2016-05-12 22:00:18      阅读:239      评论:0      收藏:0      [点我收藏+]

标签:

    可以把线程归属到某一个线程组中,线程组中可以有线程对象,也可以有线程组,组中还可以有线程。这样的组织结构有些类似于树的形式,如图所示。

技术分享

    线程组的作用是,可以批量的管理线程或线程组对象,有效地对线程或线程组对象进行组织。

1、线程对象关联线程组:1级关联

    所谓的1级关联就是父对象中有子对象,但并不创建子孙对象。这种情况经常出现在开发中,比如创建一些线程时,为了有效地对这些线程进行组织管理,通常的情况下是创建一个线程组,然后再将部分线程归属到该组中。这样的处理可以对零散的线程对象进行有效的组织与规划。

public class MyThread1 extends Thread {
    @Override
    public void run() {
        try{
            while(!Thread.currentThread().isInterrupted()) {
                System.out.println("ThreadName="
                        + Thread.currentThread().getName());
                Thread.sleep(4000);
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}
public class MyThread2 extends Thread{
    @Override
    public void run() {
        try{
            while(!Thread.currentThread().isInterrupted()) {
                System.out.println("ThreadName="
                        + Thread.currentThread().getName());
                Thread.sleep(4000);
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}
public class Run {
    public static void main(String[] args) throws InterruptedException {
        MyThread1 t1 = new MyThread1();
        MyThread2 t2 = new MyThread2();
        ThreadGroup group = new ThreadGroup("lcw的线程组");

        Thread aThread = new Thread(group, t1);
        Thread bThread = new Thread(group, t2);
        aThread.start();
        bThread.start();

        System.out.println("活动的线程数为:" + group.activeCount());
        Thread.sleep(1000);
        System.out.println("线程组的名称为:" + group.getName());
    }
}
活动的线程数为:2
ThreadName=Thread-3
ThreadName=Thread-2
线程组的名称为:lcw的线程组
ThreadName=Thread-3
ThreadName=Thread-2
ThreadName=Thread-3
ThreadName=Thread-2
......
    控制台中打印的信息表示线程组中有两个线程,并且打印出了线程组的名称。另外,两个线程一直无限地并且每隔3秒打印日志。

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

    所谓的多级关联就是父对象中有子对象,子对象中再创建子对象,也就是出现子孙对象的效果了。但是此种写法在开发中不太常见,如果线程树结构设计得非常复杂反而不利于线程对象的管理,但JDK却提供了支持多级关联的线程树结构。

/**
 * 在main组中添加一个线程组A,然后在这个A组中添加线程对象X和Y
 * 方法activeGroupCount()和activeCount()的值不是固定的,
 * 是系统中环境的一个快照
 */
public class Run {
    public static void main(String[] args) throws InterruptedException {
        ThreadGroup mainGroup = Thread.currentThread().getThreadGroup();
        //ThreadGroup(父线程组,子线程组名)
        ThreadGroup group = new ThreadGroup(mainGroup, "AA");

        Runnable runnable = new Runnable() {
            public void run() {
                try {
                    System.out.println("runMethod!");
                    Thread.sleep(1000); //线程必须在运行状态才可以受组管理
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        };

        Thread newThread = new Thread(group, runnable);
        newThread.setName("X");
        newThread.start(); //线程必须启动然后才归到组A中

        Thread newThread2 = new Thread(group, runnable);
        newThread2.setName("Y");
        newThread2.start(); //线程必须启动然后才归到组A中

        ///
        ThreadGroup[] listGroup = new ThreadGroup[Thread.currentThread()
                .getThreadGroup().activeGroupCount()];
        Thread.currentThread().getThreadGroup().enumerate(listGroup);
        System.out.println("main线程中有多少个子线程组:" + listGroup.length
                +", 名字为:" +listGroup[0].getName()
                +",这个子线程组有多少个线程:" + listGroup[0].activeCount());

        Thread[] listThread = new Thread[listGroup[0].activeCount()];
        listGroup[0].enumerate(listThread);
        System.out.println(listThread[0].getName());
        System.out.println(listThread[1].getName());
    }
}
main线程中有多少个子线程组:1, 名字为:AA,这个子线程组有多少个线程:2
X
Y
runMethod!
runMethod!
    本程序代码的结构就是main组创建一个新组,然后又在该新组中添加了线程。

3、线程组自动归属特性

    自动归属就是自动归到当前线程组中。

/**
 * 方法activeGroupCount()取得当前线程组对象中的子线程组数量
 * 方法enumerate()的作用是将线程组中的子线程以复数的形式
 *     拷贝到ThreadGroup[]数组对象中
 */
public class Run {
    public static void main(String[] args) throws InterruptedException {
        System.out.println("A处线程名:" + Thread.currentThread().getName()
                + ",所属的线程组名为:"+Thread.currentThread().getThreadGroup().getName()
                + ", 中有线程组数量:"+Thread.currentThread().getThreadGroup().activeGroupCount());
        ThreadGroup group = new ThreadGroup("新的组"); //自动加到main组中
        System.out.println("B处线程名:" + Thread.currentThread().getName()
                + ",所属的线程组名为:"+Thread.currentThread().getThreadGroup().getName()
                + ", 中有线程组数量:"+Thread.currentThread().getThreadGroup().activeGroupCount());

        ThreadGroup[] threadGroups = new ThreadGroup[Thread.currentThread()
                .getThreadGroup().activeGroupCount()];
        Thread.currentThread().getThreadGroup().enumerate(threadGroups);

        System.out.println("第一个线程组名称为:" +threadGroups[0].getName());
    }
}
A处线程名:main,所属的线程组名为:main, 中有线程组数量:0
B处线程名:main,所属的线程组名为:main, 中有线程组数量:1
第一个线程组名称为:新的组
    本实验要证明的是,在实例化一个ThreadGroup线程组x时如果不指定所属的线程组,则x线程组自动归到当前线程对象所属的线程组中,也就是隐式地在一个线程组中添加了一个子线程组,所以在控制台中打印的线程组数量值由0变成了1.

4、获取根线程组

public class Run {
    public static void main(String[] args) throws InterruptedException {
        System.out.println("线程:"+Thread.currentThread().getName()
                +",所在的线程组名为:"+Thread.currentThread().getThreadGroup().getName());

        System.out.println("main线程所在的线程组的父线程组的名称是:"
                +Thread.currentThread().getThreadGroup().getParent().getName());

        System.out.println("main线程所有的线程组的父线程组的你线程组的名称是:"
                +Thread.currentThread().getThreadGroup().getParent().getParent().getName());
    }
}
线程:main,所在的线程组名为:main
main线程所在的线程组的父线程组的名称是:system
Exception in thread "main" java.lang.NullPointerException
    运行结果说明JVM的根线程组就是system,再取其父线程组则出现空异常。

5、线程组里加线程组

public class Run {
    public static void main(String[] args) throws InterruptedException {
        System.out.println("线程组名称:"
                + Thread.currentThread().getThreadGroup().getName());
        System.out.println("线程组中活动的线程数量:"
                +Thread.currentThread().getThreadGroup().activeCount());
        System.out.println("线程组中线程组的数据--加之前:"
                +Thread.currentThread().getThreadGroup().activeGroupCount());

        ThreadGroup newGroup = new ThreadGroup(Thread.currentThread()
                .getThreadGroup(), "newGroup");
        System.out.println("线程组中线程组的数量--加之后:"
                +Thread.currentThread().getThreadGroup().activeGroupCount());
        System.out.println("父线程组名称:"
                +Thread.currentThread().getThreadGroup().getParent().getName());
    }
}
线程组名称:main
线程组中活动的线程数量:2
线程组中线程组的数据--加之前:0
线程组中线程组的数量--加之后:1
父线程组名称:system

6、组内的线程批量停止

public class MyThread extends Thread {
    public MyThread(ThreadGroup group, String name) {
        super(group, name);
    }

    @Override
    public void run() {
        System.out.println("ThreadName=" + Thread.currentThread().getName()
                +",准备开始死循环了");
        while(!this.isInterrupted()){
        }
        System.out.println("ThreadName=" + Thread.currentThread().getName()
                +",结束了");
    }
}
public class Run {
    public static void main(String[] args) throws InterruptedException {
        ThreadGroup group = new ThreadGroup("myThreadGroup");
        for (int i=0; i<3; i++) {
            MyThread thread = new MyThread(group, "线程"+(i+1));
            thread.start();
        }
        Thread.sleep(1000);
        group.interrupt();
        System.out.println("调用了interrupt方法");
    }
}
ThreadName=线程1,准备开始死循环了
ThreadName=线程3,准备开始死循环了
ThreadName=线程2,准备开始死循环了
调用了interrupt方法
ThreadName=线程3,结束了
ThreadName=线程1,结束了
ThreadName=线程2,结束了

7、递归与非递归取得组内对象

public class Run {
    public static void main(String[] args) throws InterruptedException {
        ThreadGroup mainGroup = Thread.currentThread().getThreadGroup();
        ThreadGroup groupA = new ThreadGroup(mainGroup, "AA");

        Runnable runnable = new Runnable() {
            public void run() {
                try {
                    System.out.println("runMethod!");
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        };

        ThreadGroup groupB = new ThreadGroup(groupA, "BB");
        //分配空间,但不一定全部用完
        ThreadGroup[] listGroup1 = new ThreadGroup[Thread.currentThread()
                .getThreadGroup().activeGroupCount()];
        //传入true是递归取得子组及子孙组
        Thread.currentThread().getThreadGroup().enumerate(listGroup1, true);
        for (int i=0; i<listGroup1.length; i++) {
            if (listGroup1[i] != null){
                System.out.println("--"+listGroup1[i].getName());
            }
        }
        ThreadGroup[] listGroup2 = new ThreadGroup[Thread.currentThread()
                .getThreadGroup().activeGroupCount()];
        Thread.currentThread().getThreadGroup().enumerate(listGroup2, false);
        for (int i=0; i<listGroup2.length; i++) {
            if (listGroup2[i] != null){
                System.out.println("**" +listGroup2[i].getName());
            }
        }
    }
}
--AA
--BB
**AA

Java多线程编程7--拾遗增补--线程组

标签:

原文地址:http://blog.csdn.net/ochangwen/article/details/51353620

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!