分享
 
 
 

Java中的线程组

王朝java/jsp·作者佚名  2008-05-19
窄屏简体版  字體: |||超大  

所有线程都隶属于一个线程组。那可以是一个默认线程组,亦可是一个创建线程时明确指定的组。在创建之初,线程被限制到一个组里,而且不能改变到一个不同的组。每个应用都至少有一个线程从属于系统线程组。若创建多个线程而不指定一个组,它们就会自动归属于系统线程组。

线程组也必须从属于其他线程组。必须在构建器里指定新线程组从属于哪个线程组。若在创建一个线程组的时候没有指定它的归属,则同样会自动成为系统线程组的一名属下。因此,一个应用程序中的所有线程组最终都会将系统线程组作为自己的“父”。

之所以要提出“线程组”的概念,很难从字面上找到原因。这多少为我们讨论的主题带来了一些混乱。一般地说,我们认为是由于“安全”或者“保密”方面的理由才使用线程组的。根据Arnold和Gosling的说法:“线程组中的线程可以修改组内的其他线程,包括那些位于分层结构最深处的。一个线程不能修改位于自己所在组或者下属组之外的任何线程”(注释①)。然而,我们很难判断“修改”在这儿的具体含义是什么。下面这个例子展示了位于一个“叶子组”内的线程能修改它所在线程组树的所有线程的优先级,同时还能为这个“树”内的所有线程都调用一个方法。

①:《The Java Programming Language》第179页。该书由Arnold和Jams Gosling编著,Addison-Wesley于1996年出版

//: TestAccess.java

// How threads can access other threads

// in a parent thread group

public class TestAccess {

public static void main(String[] args) {

ThreadGroup

x = new ThreadGroup("x"),

y = new ThreadGroup(x, "y"),

z = new ThreadGroup(y, "z");

Thread

one = new TestThread1(x, "one"),

two = new TestThread2(z, "two");

}

}

class TestThread1 extends Thread {

private int i;

TestThread1(ThreadGroup g, String name) {

super(g, name);

}

void f() {

i++; // modify this thread

System.out.println(getName() + " f()");

}

}

class TestThread2 extends TestThread1 {

TestThread2(ThreadGroup g, String name) {

super(g, name);

start();

}

public void run() {

ThreadGroup g =

getThreadGroup().getParent().getParent();

g.list();

Thread[] gAll = new Thread[g.activeCount()];

g.enumerate(gAll);

for(int i = 0; i

gAll[i].setPriority(Thread.MIN_PRIORITY);

((TestThread1)gAll[i]).f();

}

g.list();

}

} ///:~

在main()中,我们创建了几个ThreadGroup(线程组),每个都位于不同的“叶”上:x没有参数,只有它的名字(一个String),所以会自动进入“system”(系统)线程组;y位于x下方,而z位于y下方。注意初始化是按照文字顺序进行的,所以代码合法。

有两个线程创建之后进入了不同的线程组。其中,TestThread1没有一个run()方法,但有一个f(),用于通知线程以及打印出一些东西,以便我们知道它已被调用。而TestThread2属于TestThread1的一个子类,它的run()非常详尽,要做许多事情。首先,它获得当前线程所在的线程组,然后利用getParent()在继承树中向上移动两级(这样做是有道理的,因为我想把TestThread2在分级结构中向下移动两级)。随后,我们调用方法activeCount(),查询这个线程组以及所有子线程组内有多少个线程,从而创建由指向Thread的句柄构成的一个数组。enumerate()方法将指向所有这些线程的句柄置入数组gAll里。然后在整个数组里遍历,为每个线程都调用f()方法,同时修改优先级。这样一来,位于一个“叶子”线程组里的线程就修改了位于父线程组的线程。

调试方法list()打印出与一个线程组有关的所有信息,把它们作为标准输出。在我们对线程组的行为进行调查的时候,这样做是相当有好处的。下面是程序的输出:

java.lang.ThreadGroup[name=x,maxpri=10]

Thread[one,5,x]

java.lang.ThreadGroup[name=y,maxpri=10]

java.lang.ThreadGroup[name=z,maxpri=10]

Thread[two,5,z]

one f()

two f()

java.lang.ThreadGroup[name=x,maxpri=10]

Thread[one,1,x]

java.lang.ThreadGroup[name=y,maxpri=10]

java.lang.ThreadGroup[name=z,maxpri=10]

Thread[two,1,z]

list()不仅打印出ThreadGroup或者Thread的类名,也打印出了线程组的名字以及它的最高优先级。对于线程,则打印出它们的名字,并接上线程优先级以及所属的线程组。注意list()会对线程和线程组进行缩排处理,指出它们是未缩排的线程组的“子”。

大家可看到f()是由TestThread2的run()方法调用的,所以很明显,组内的所有线程都是相当脆弱的。然而,我们只能访问那些从自己的system线程组树分支出来的线程,而且或许这就是所谓“安全”的意思。我们不能访问其他任何人的系统线程树。

线程组的控制

抛开安全问题不谈,线程组最有用的一个地方就是控制:只需用单个命令即可完成对整个线程组的操作。下面这个例子演示了这一点,并对线程组内优先级的限制进行了说明。括号内的注释数字便于大家比较输出结果:

//: ThreadGroup1.java

// How thread groups control priorities

// of the threads inside them.

public class ThreadGroup1 {

public static void main(String[] args) {

// Get the system thread & print its Info:

ThreadGroup sys =

Thread.currentThread().getThreadGroup();

sys.list(); // (1)

// Reduce the system thread group priority:

sys.setMaxPriority(Thread.MAX_PRIORITY - 1);

// Increase the main thread priority:

Thread curr = Thread.currentThread();

curr.setPriority(curr.getPriority() + 1);

sys.list(); // (2)

// Attempt to set a new group to the max:

ThreadGroup g1 = new ThreadGroup("g1");

g1.setMaxPriority(Thread.MAX_PRIORITY);

// Attempt to set a new thread to the max:

Thread t = new Thread(g1, "A");

t.setPriority(Thread.MAX_PRIORITY);

g1.list(); // (3)

// Reduce g1's max priority, then attempt

// to increase it:

g1.setMaxPriority(Thread.MAX_PRIORITY - 2);

g1.setMaxPriority(Thread.MAX_PRIORITY);

g1.list(); // (4)

// Attempt to set a new thread to the max:

t = new Thread(g1, "B");

t.setPriority(Thread.MAX_PRIORITY);

g1.list(); // (5)

// Lower the max priority below the default

// thread priority:

g1.setMaxPriority(Thread.MIN_PRIORITY + 2);

// Look at a new thread's priority before

// and after changing it:

t = new Thread(g1, "C");

g1.list(); // (6)

t.setPriority(t.getPriority() -1);

g1.list(); // (7)

// Make g2 a child Threadgroup of g1 and

// try to increase its priority:

ThreadGroup g2 = new ThreadGroup(g1, "g2");

g2.list(); // (8)

g2.setMaxPriority(Thread.MAX_PRIORITY);

g2.list(); // (9)

// Add a bunch of new threads to g2:

for (int i = 0; i

new Thread(g2, Integer.toString(i));

// Show information about all threadgroups

// and threads:

sys.list(); // (10)

System.out.println("Starting all threads:");

Thread[] all = new Thread[sys.activeCount()];

sys.enumerate(all);

for(int i = 0; i if(!all[i].isAlive())all[i].start();// Suspends & Stops all threads in// this group and its subgroups:System.out.println("All threads started");sys.suspend(); // Deprecated in Java 1.2// Never gets here...System.out.println("All threads suspended");sys.stop(); // Deprecated in Java 1.2System.out.println("All threads stopped");}} ///:~下面的输出结果已进行了适当的编辑,以便用一页能够装下(java.lang.已被删去),而且添加了适当的数字,与前面程序列表中括号里的数字对应:(1) ThreadGroup[name=system,maxpri=10]Thread[main,5,system](2) ThreadGroup[name=system,maxpri=9]Thread[main,6,system](3) ThreadGroup[name=g1,maxpri=9]Thread[A,9,g1](4) ThreadGroup[name=g1,maxpri=

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有