关闭

Java多线程16:线程组

标签: java多线程线程
300人阅读 评论(0) 收藏 举报
分类:

线程组

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

 

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

 

线程关联线程组:1级关联

所谓1级关联就是父对象中有子对象,但并不创建孙对象。这种情况在开发中很常见,比如创建一些线程时,为了有效对这些线程进行阻止管理,通常情况下是创建一个线程组,然后再将部分线程归属到该组中,以此来对零散的线程对象进行有效的管理。

看一下简单的1级关联的例子:

复制代码
public class MyThread49 implements Runnable
{
    public void run()
    {
        try
        {
            while (!Thread.currentThread().isInterrupted())
            {
                System.out.println("ThreadName = " + Thread.currentThread().getName());
                Thread.sleep(3000);
            }
        }
        catch (InterruptedException e)
        {
            e.printStackTrace();
        }
    }
}
复制代码
复制代码
public static void main(String[] args)
{
    MyThread49 mt0 = new MyThread49();
    MyThread49 mt1 = new MyThread49();
    ThreadGroup tg = new ThreadGroup("新建线程组1");
    Thread t0 = new Thread(tg, mt0);
    Thread t1 = new Thread(tg, mt1);
    t0.start();
    t1.start();
    System.out.println("活动的线程数为:" + tg.activeCount());
    System.out.println("线程组的名称为:" + tg.getName());
}
复制代码

看一下运行结果:

复制代码
活动的线程数为:2
ThreadName = Thread-1
ThreadName = Thread-0
线程组的名称为:新建线程组1
ThreadName = Thread-1
ThreadName = Thread-0
ThreadName = Thread-1
ThreadName = Thread-0
ThreadName = Thread-1
ThreadName = Thread-0
...
复制代码

控制台上打印出的信息表示线程组中有两个线程,并且打印出了线程组的名称。另外,两个线程无限隔3秒打印,也符合代码预期

 

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

所谓的多级关联就是父对象中有子对象,子对象中再创建子对象买也就出现了子孙的效果了。但是这种写法在开发中不太常见,因为线程树如果涉及得复杂反而不利于线程对象的管理,不过JDK确实提供了多级关联的线程树结构。

多级关联的代码就不写了,简单看一下怎么使用关机关联,查看下JDK API的ThreadGroup构造方法:

注意一下第二个,假如要使用多级关联一般就是用第二个构造函数。第一个参数表示新线程组的父线程组,第二个参数表示新线程组的名称,有了父线程组和新线程组的名称,自然可以构造出一个新的线程组来了。

当然用第一个构造方法也是可以的,下一部分就会提到。

另外注意一点,线程必须启动后才能归到指定线程组中

 

线程组自动归属特性

自动归属的意思就是自动归到当前线程组中,看一下例子:

复制代码
public static void main(String[] args)
{
    System.out.println("A处线程:" + 
        Thread.currentThread().getName() + 
        ", 所属线程:" + 
        Thread.currentThread().getThreadGroup().getName() + 
        ", 组中有线程组数量:" + 
        Thread.currentThread().getThreadGroup().activeGroupCount());
    ThreadGroup group = new ThreadGroup("新的组");
    System.out.println("B处线程:" + 
        Thread.currentThread().getName() + 
        ", 所属线程:" + 
        Thread.currentThread().getThreadGroup().getName() + 
        ", 组中有线程组数量:" + 
    Thread.currentThread().getThreadGroup().activeGroupCount());
    ThreadGroup[] tg = new ThreadGroup[Thread.currentThread().getThreadGroup().activeGroupCount()];
    Thread.currentThread().getThreadGroup().enumerate(tg);
    for (int i = 0; i < tg.length; i++)
        System.out.println("第一个线程组名称为:" + tg[i].getName());
}
复制代码

看一下运行结果:

A处线程:main, 所属线程:main, 组中有线程组数量:0
B处线程:main, 所属线程:main, 组中有线程组数量:1
第一个线程组名称为:新的组

从结果看,实例化了一个group出来,没有指定线程组,那么自动归到当前线程所属的线程组中,也就是隐式地在一个线程组中添加了一个子线程组。

 

根线程组

看一下根线程组: 

public static void main(String[] args)
{
    System.out.println(Thread.currentThread().getThreadGroup().getParent().getName());
    System.out.println(Thread.currentThread().getThreadGroup().getParent().getParent().getName());
}

看一下运行结果:

system
Exception in thread "main" java.lang.NullPointerException
    at com.xrq.example.e49.TestMain49.main(TestMain49.java:11)

运行结果可以得出两个结论:

1、根线程组就是系统线程组system

2、抛空指针异常是因为系统线程组上已经没有线程组了,所以system的getParent()方法返回的是null,对null调用getName()方法自然是NullPointerException

关于根线程组,看一下ThreadGroup的源码:

复制代码
/**
 * Creates an empty Thread group that is not in any Thread group. 
 * This method is used to create the system Thread group.
 */
private ThreadGroup() {    // called from C code
this.name = "system";
this.maxPriority = Thread.MAX_PRIORITY;
}
复制代码

一个私有构造方法,说明不是对开发者开放的。注释上已经写得很清楚了,这是C代码调用的,用于构建系统线程组。

 

批量停止组内线程

使用线程组自然是要对线程做批量管理的,到目前为止我们似乎都没有看见如何对线程组内的线程做批量操作,最后来看一下批量操作线程组内的线程:

复制代码
public class MyThread50 extends Thread
{
    public MyThread50(ThreadGroup tg, String name)
    {
        super(tg, name);
    }
    
    public void run()
    {
        System.out.println("ThreadName = " + Thread.currentThread().getName() + 
                "准备开始死循环了");
        while (!this.isInterrupted()){}
        System.out.println("ThreadName = " + Thread.currentThread().getName() + 
                "结束了");
    }
}
复制代码

开3个线程:

复制代码
public static void main(String[] args) throws InterruptedException
{
    ThreadGroup tg = new ThreadGroup("我的线程组");
    MyThread50 mt = null;
    for (int i = 0; i < 3; i++)
    {
        mt = new MyThread50(tg, "线程" + i);
        mt.start();
    }
    Thread.sleep(5000);
    tg.interrupt();
    System.out.println("调用了interrupt()方法");
}
复制代码

看一下运行结果:

复制代码
ThreadName = 线程0准备开始死循环了
ThreadName = 线程2准备开始死循环了
ThreadName = 线程1准备开始死循环了
调用了interrupt()方法
ThreadName = 线程2结束了
ThreadName = 线程1结束了
ThreadName = 线程0结束了
复制代码

看到调用了ThreadGroup中的interrupt()方法批量中断了线程组内的线程,这就是ThreadGroup的作用。更多线程组的操作可以查看JDK API。

0
0
查看评论

java 多线程

线程的六种状态 1.线程的六种状态 1.新建状态(new 线程对象) 2.运行状态(调用start) 3.受阻塞状态(等待cpu的执行资源) 4.休眠状态(调用了sleep(休眠时间)方法) 5.等待状态(调用了wait()方法) 6.死亡状态(...
  • X18621144576
  • X18621144576
  • 2018-02-06 20:38
  • 24

java多线程和队列实例

java多线程和队列实例
  • cai_chinasoft
  • cai_chinasoft
  • 2016-06-02 13:54
  • 12823

多线程_线程组的概述和使用

package cn.itcast_06; /* * 线程组:把多个线程组全在一起。 * 它可以对一批线程进行分类管理,Java允许程序直接对线程组进行控制。 */ public class ThreadGroupDemo { public static void main(String[...
  • L1585931143
  • L1585931143
  • 2017-03-19 00:03
  • 253

程序猿的多线程的生活

转载  + 个人体会,分享如下,请高手指点:  生活中,总会出现这样的一幕:当自己正在一个很复杂的业务编写算法的紧要关头——突然,同事(同学)反映网站的某某功能不能运行了,要你给修复。接着几分钟后,你的团队负责人要求你解释一下昨天发表的有关项目的问题,或者更干脆一些你是一个专注...
  • u010700335
  • u010700335
  • 2014-09-28 11:35
  • 923

Java多线程16:线程组

线程组 可以把线程归属到某一个线程组中,线程组中可以有线程对象,也可以有线程组,组中还可以有线程,这样的组织结构有点类似于树的形式,如图所示:   线程组的作用是:可以批量管理线程或线程组对象,有效地对线程或线程组对象进行组织。   线程关联...
  • tianya3530
  • tianya3530
  • 2017-01-03 11:31
  • 300

volatile —多线程程序员的最好朋友

volatile —多线程程序员的最好朋友              作者:Andrei Alexandrescu     ...
  • liujinz72213
  • liujinz72213
  • 2007-04-29 21:36
  • 731

Java 多线程(七)——线程组与线程池

Java中使用ThreadGroup来表示线程组,它可以对一批线程进行分类管理。对线程组的控管理,即同时控制线程组里面的这一批线程。
  • Zen99T
  • Zen99T
  • 2016-05-02 15:17
  • 8028

Java 线程组和线程池区别

线程组: 线程组存在的意义,首要原因是安全。 java默认创建的线程都是属于系统线程组,而同一个线程组的线程是可以相互修改对方的数据的。 但如果在不同的线程组中,那么就不能“跨线程组”修改数据,可以从一定程度上保证数据安全. 线程池: 线程池存在的意义,首要作用是效率。 线程的创建和结束都需要耗...
  • QQ578473688
  • QQ578473688
  • 2017-01-15 14:45
  • 10518

Java程序员从笨鸟到菜鸟之(十一)多线程讲解

本文来自:曹胜欢博客专栏。转载请注明出处:http://blog.csdn.net/csh624366188         多线程是java应用程序的一个特点,掌握java的多线程也是作为一java程序员必备的知识。多线程指的是在单个...
  • csh624366188
  • csh624366188
  • 2012-03-04 17:01
  • 27162

多线程

------- android培训、java培训、期待与您交流! ---------- 多线程概述 进程:正在进行中的程序。线程:进程中的独立控制单元。线程控制着进程的执行。 一个进程中至少有一个线程。 jvm启动时有一个java.exe进程,该进程至少有一个主线程负责程序的执行...
  • vivian5350
  • vivian5350
  • 2012-11-29 17:18
  • 317
    个人资料
    • 访问:46864次
    • 积分:835
    • 等级:
    • 排名:千里之外
    • 原创:19篇
    • 转载:112篇
    • 译文:0篇
    • 评论:3条
    文章分类
    最新评论