基础概念(百科)
在Java中每一个线程都归属于某个线程组管理的一员,例如在主函数main()主工作流程中产生一个线程,则产生的线程属于main这个线程组管理的一员。简单地说,线程组(ThreadGroup)就是由线程组成的管理线程的类,这个类是java.lang.ThreadGroup类。
定义一个线程组,通过以下代码可以实现。
ThreadGroup group=new ThreadGroup("group");
Thread thread=new Thread(group,"the first thread of group");
ThreadGroup类中的某些方法,可以对线程组中的线程产生作用。例如,setMaxPriority()方法可以设定线程组中的所有线程拥有最大的优先权。
所有线程都隶属于一个线程组。那可以是一个默认线程组,亦可是一个创建线程时明确指定的组。在创建之初,线程被限制到一个组里,而且不能改变到一个不同的组。每个应用都至少有一个线程从属于系统线程组。若创建多个线程而不指定一个组,它们就会自动归属于系统线程组。
线程组也必须从属于其他线程组。必须在构建器里指定新线程组从属于哪个线程组。若在创建一个线程组的时候没有指定它的归属,则同样会自动成为系统线程组的一名属下。因此,一个应用程序中的所有线程组最终都会将系统线程组作为自己的“父”
之所以要提出“线程组”的概念,一般认为,是由于“安全”或者“保密”方面的理由。根据Arnold和Gosling的说法:“线程组中的线程可以修改组内的其他线程,包括那些位于分层结构最深处的。一个线程不能修改位于自己所在组或者下属组之外的任何线程””(注释①)
①:《The Java Programming Language》第179页。该书由Arnold和James Gosling编著,Addison-Wesley于1996年出版
线程组函数释义
①定义线程组
ThreadGroup类中有 2个构造方法,它们用来定义线程组。这 2个构造方法的使用格 式如下:
public ThreadGroup(String name);
public ThreadGroup(ThreadGroup parent,String name);
比如,创建一个名为fruit的线程组k,可用如下语句:
ThreadGroup k=new ThreadGroup(“fruit”);
如果一个线程组有父线程组,则可以在定义时,用第二个构造方法指出父线程组的名 字。比如:
ThreadGroup k=new ThreadGroup(products,“fruit”);
②获得线程组中的信息
ThreadGroup类中有几个方法可用来获得线程组中有关线程和子线程的信息,这些信 息包括线程组名字、线程组中可运行线程的数目、线程组中线程的最大优先级、线程组中各 线程的名字等。这些方法有:
public int activeCount(); // 获得当前线程组中线程数目, 包括可运行和不可运行的
public int activeGroupCount(); //获得当前线程组中活动的子线程组的数目
public int enumerate(Thread list[]); //列举当前线程组中的线程
public int enumerate(ThreadGroup list[]); //列举当前线程组中的子线程组
public final int getMaxPriority(); //获得当前线程组中最大优先级
public final String getName(); //获得当前线程组的名字
public final ThreadGroup getParent(); //获得当前线程组的父线程组
public boolean parentOf(ThreadGroup g); //判断当前线程组是否为指定线程的父线程
public boolean isDaemon(); //判断当前线程组中是否有监护线程
public void list(); //列出当前线程组中所有线程和子线程名
③对线程组操作
ThreadGroup类中的方法都是以线程组为操作目标的。其中,包括设置线程组中线程 的最大优先级方法、将线程组中所有线程挂起或恢复到可运行状态的方法、终止线程组中所 有线程的方法等。
对线程组进行操作的方法如下所示:
public final void resume(); //使被挂起的当前组内的线程恢复到可运行状态
public final void setDaemon (boolean daemon); //指定一个线程为当前线程组的监护线程
public final void setMaxPriority(int pri); //设置当前线程组允许的最大优先级
public final void stop();//终止当前线程组中所有线程
public final void suspend(); //挂起当前线程组中所有线程
public String toStrinng(); //将当前线程组转换为String类的对象
线程组管理线程池范例
/**
* 当创建了好几个线程的时候,很多线程的工作任务是类似或者一致的,这样我们就可以使用ThreadGroup来管理他
* 们,ThreadGroup可以随时的获取在他里面的线程的运行状态,信息,或者一条命令关闭掉这个group里面的所有线 程,非常的简单实用
*
* @author Administrator
*
*/
public class SearchTask implements Runnable {
public SearchTask(Result result) {
this.result = result;
}
private Result result;
@Override
public void run() {
String name = Thread.currentThread().getName();
System.out.println("Thread Start " + name);
try {
doTask();
result.setName(name);
} catch (InterruptedException e) {
System.out.printf("Thread %s: Interrupted\n", name);
return;
}
System.out.println("Thread end " + name);
}
private void doTask() throws InterruptedException {
Random random = new Random((new Date()).getTime());
int value = (int) (random.nextDouble() * 100);
System.out.printf("Thread %s: %d\n", Thread.currentThread().getName(),
value);
TimeUnit.SECONDS.sleep(value);
}
public static void main(String[] args) {
// 创建5个线程,并入group里面进行管理
ThreadGroup threadGroup = new ThreadGroup("Searcher");
Result result = new Result();
SearchTask searchTask = new SearchTask(result);
for (int i = 0; i < 5; i++) {
Thread thred = new Thread(threadGroup, searchTask);
thred.start();
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
// 通过这种方法可以看group里面的所有信息
System.out.printf("Number of Threads: %d\n", threadGroup.activeCount());
System.out.printf("Information about the Thread Group\n");
threadGroup.list();
// 这样可以复制group里面的thread信息
Thread[] threads = new Thread[threadGroup.activeCount()];
threadGroup.enumerate(threads);
for (int i = 0; i < threadGroup.activeCount(); i++) {
System.out.printf("Thread %s: %s\n", threads[i].getName(),
threads[i].getState());
}
waitFinish(threadGroup);
// 将group里面的所有线程都给interpet
threadGroup.interrupt();
}
private static void waitFinish(ThreadGroup threadGroup) {
while (threadGroup.activeCount() > 9) {
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
线程组和线程池的区别
二者最直观的区别是,线程池就像一台水轮机,它的叶片就像线程,可以循环不停,看起来只要水源不断,叶片就可以不停的周期性的工作。而线程组,只是管理一个或多个线程的Manager,而且它所管理的线程生命周期一旦结束,将永远停止,无法周期执行任务.