java中线程组threadgroup与线程池的区别及示例-kb88凯时官网登录

来自:网络
时间:2023-05-17
阅读:
免费资源网 - https://freexyz.cn/
目录

线程组概念理解

在java的多线程处理中有线程组threadgroup的概念,threadgroup是为了方便线程管理出现了,可以统一设定线程组的一些属性,比如setdaemon,设置未处理异常的处理方法,设置统一的安全策略等等;也可以通过线程组方便的获得线程的一些信息。

每一个threadgroup都可以包含一组的子线程和一组子线程组,在一个进程中线程组是以树形的方式存在,通常情况下根线程组是system线程组。system线程组下是main线程组,默认情况下第一级应用自己的线程组是通过main线程组创建出来的。

我们可以通过下面代码片段看下一个简单的java application中线程组的情况:

package cn.outofmemory.concurrent;
public class threadgroupdemo {
	public static void main(string[] args) {
		printgroupinfo(thread.currentthread());
		thread appthread = new thread(new runnable(){
			@override
			public void run() {
				for (int i=0;i<5;i  ) {
					system.out.println("do loop "   i);
				}
			}
		});
		appthread.setname("appthread");
		appthread.start();
		printgroupinfo(appthread);
	}
	static void printgroupinfo(thread t) {
		threadgroup group = t.getthreadgroup();
		system.out.println("thread "   t.getname()   " group name is " 
				  group.getname()  " max priority is "   group.getmaxpriority()
				  " thread count is "   group.activecount());
		threadgroup parent=group;
		do {
			threadgroup current = parent;
			parent = parent.getparent();
			if (parent == null) {
				break;
			}
			system.out.println(current.getname()   "'s parent is "   parent.getname());
		} while (true);
		system.out.println("--------------------------");
	}
}

这段代码打印结果如下:

thread main group name is main max priority is 10 thread count is 1
main's parent is system
--------------------------
thread appthread group name is main max priority is 10 thread count is 2
main's parent is system
--------------------------
do loop 0
do loop 1
do loop 2
do loop 3
do loop 4

在创建线程时可以通过构造函数指定其所在的线程组,如下代码:

threadgroup group=new threadgroup("worker");
thread thread=new thread(group,"the first thread of group");

通常情况下我们创建线程时可能不设置线程组,这时候创建的线程会和创建该线程的线程在一个组里面

线程组实践

下面通过实例演示如何使用threadgroup,该实例中设定了线程组的daemon属性,设置了线程组内线程的最大优先级,通过继承threadgroup的方式,重写了该线程组对于未处理异常的处理逻辑。

请看下面代码:

package cn.outofmemory.concurrent;
import java.net.socketexception;
public class threadgroupdemo2 {
	public static void main(string[] args) {
		threadgroup spidergroup = new spiderthreadgroup("spidergroup");
		//可以统一设定线程是否为守护线程
		spidergroup.setdaemon(true);
		//可以设置线程组内的最大优先级
		spidergroup.setmaxpriority(thread.norm_priority);
		//初始化线程
		thread spiderthread = new thread(spidergroup, new runnable() {
			@override
			public void run() {
				throw new runtimeexception(new socketexception());
			}
		});
		//启动线程
		spiderthread.start();
	}
	/**
	 * 此类从threadgroup类继承重写了其uncaughtexception方法,对于socketexception进行了特殊处理
	 * @author outofmemory.cn
	 *
	 */
	static class spiderthreadgroup extends threadgroup {
		public spiderthreadgroup(string name) {
			super(name);
		}
		public void uncaughtexception(thread t, throwable e) {
			if (e.getcause() instanceof socketexception) {
				system.out.println("socket exception should be process");
			} else {
				super.uncaughtexception(t, e);
			}
		}
	}
}

上面的实例代码会输出如下内容:

socket exception should be process

说明未处理异常已经被统一处理了。

下面我们通过另外一个示例演示如何通过线程组,方便的获得应用中一共有多少个活动线程,并打印这些活动线程的名字。

package cn.outofmemory.concurrent;
public class threaddemo3 {
	public static void main(string[] args) {
		threadgroup g = thread.currentthread().getthreadgroup();
		while (g != null) {
			threadgroup temp = g.getparent();
			if (temp == null) {
				break;
			}
			g = temp;
		}
		//现在g就是跟线程组
		system.out.println("active count is "   g.activecount());
		thread[] all = new thread[g.activecount()];
		g.enumerate(all);
		for (thread t : all) {
			system.out.println(t.getname());
		}
	}
}

你不妨猜猜这个小程序的输出结果,按理说我只有一个main方法,没有任何自定义线程,那么会输出几个线程呢?

下面是输出结果:

active count is 5
reference handler
finalizer
signal dispatcher
attach listener
main

一共有5个线程,这5个线程除了main是我们自己代码run所在的线程,其他都是虚拟机启动的线程。是不是出乎你的意外了?

线程组和线程池的区别

线程组和线程池是两个不同的概念,他们的作用完全不同,线程组是为了方便线程的管理,线程池是为了管理线程的生命周期,复用线程,减少创建销毁线程的开销。

在构建线程池时,threadpoolexcutor的构造方法中,生成线程工厂的参数threadfactory接口的实现类defaultthreadfactory中有个属性,threadgroup

 public threadpoolexecutor(int corepoolsize,
                              int maximumpoolsize,
                              long keepalivetime,
                              timeunit unit,
                              blockingqueue workqueue,
                              threadfactory threadfactory,
                              rejectedexecutionhandler handler) {
        if (corepoolsize < 0 ||
            maximumpoolsize <= 0 ||
            maximumpoolsize < corepoolsize ||
            keepalivetime < 0)
            throw new illegalargumentexception();
        if (workqueue == null || threadfactory == null || handler == null)
            throw new nullpointerexception();
        this.corepoolsize = corepoolsize;
        this.maximumpoolsize = maximumpoolsize;
        this.workqueue = workqueue;
        this.keepalivetime = unit.tonanos(keepalivetime);
        this.threadfactory = threadfactory;
        this.handler = handler;
    }
public class defaultthreadfactory implements threadfactory {
    private static final atomicinteger poolid = new atomicinteger();
    private final atomicinteger nextid = new atomicinteger();
    private final string prefix;
    private final boolean daemon;
    private final int priority;
    protected final threadgroup threadgroup;
    ......
}
免费资源网 - https://freexyz.cn/
返回顶部
顶部
网站地图