日期:2011-03-22 16:16:00 来源:本站整理
java的线程组[Java编程]
本文“java的线程组[Java编程]”是由七道奇为您精心收集,来源于网络转载,文章版权归文章作者所有,本站不对其观点以及内容做任何评价,请读者自行判断,以下是其具体内容:
全部线程都隶属于一个线程组.那可以是一个默许线程组,亦但是一个成立线程时明确指定的组.在成立之初,线程被限制到一个组里,并且不能改变到一个差别的组.每个利用都至少有一个线程从属于系统线程组.若成立多个线程而不指定一个组,它们就会自动归属于系统线程组.
线程组也必须从属于其他线程组.必须在构建器里指定新线程组从属于哪个线程组.若在成立一个线程组的时刻没有指定它的归属,则一样会自动成为系统线程组的一名部属.因此,一个利用程序中的全部线程组终究城市将系统线程组作为自己的“父”.
之所以要提出“线程组”的概念,很难从字面上找到缘由.这多少为我们谈论的主题带来了一些混乱.普通地说,我们认为是由于“安全”大概“保密”方面的来由才利用线程组的.按照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.length; 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线程组树分支出来的线程,并且大概这就是所谓“安全”的意思.我们不能拜候其他任何人的系统线程树.
1. 线程组的掌握
抛开安全问题不谈,线程组最有效的一个地方就是掌握:只需用单个号令便可完成对整个线程组的操作.下面这个例子演示了这一点,并对线程组内优先级的限制举行了阐明.括号内的注释数字便于大家对比输出后果:
//: 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 < 5; 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 < all.length; 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.2 System.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=8] Thread[A,9,g1] (5) ThreadGroup[name=g1,maxpri=8] Thread[A,9,g1] Thread[B,8,g1] (6) ThreadGroup[name=g1,maxpri=3] Thread[A,9,g1] Thread[B,8,g1] Thread[C,6,g1] (7) ThreadGroup[name=g1,maxpri=3] Thread[A,9,g1] Thread[B,8,g1] Thread[C,3,g1] (8) ThreadGroup[name=g2,maxpri=3] (9) ThreadGroup[name=g2,maxpri=3] (10)ThreadGroup[name=system,maxpri=9] Thread[main,6,system] ThreadGroup[name=g1,maxpri=3] Thread[A,9,g1] Thread[B,8,g1] Thread[C,3,g1] ThreadGroup[name=g2,maxpri=3] Thread[0,6,g2] Thread[1,6,g2] Thread[2,6,g2] Thread[3,6,g2] Thread[4,6,g2] Starting all threads: All threads started
全部程序都至少有一个线程在运行,并且main()采纳的第一项行动就是调用Thread的一个static(静态)办法,名为currentThread().从这个线程开始,线程组将被成立,并且会为后果调用list().输出以下:
(1) ThreadGroup[name=system,maxpri=10] Thread[main,5,system]
我们可以看到,主线程组的名字是system,而主线程的名字是main,并且它从属于system线程组.
第二个操练显示出system组的最高优先级可以削减,并且main线程可以增大自己的优先级:
(2) ThreadGroup[name=system,maxpri=9] Thread[main,6,system]
第三个操练成立一个新的线程组,名为g1;它自动从属于system线程组,因为并没有明确指定它的归属关系.我们在g1内部安排了一个新线程,名为A.随后,我们试着将这个组的最大优先级设到最高的级别,并将A的优先级也设到最高一级.后果以下:
(3) ThreadGroup[name=g1,maxpri=9] Thread[A,9,g1]
可以看出,不大概将线程组的最大优先级设为高于它的父线程组.
第四个操练将g1的最大优先级降低两级,然后试着把它升至Thread.MAX_PRIORITY.后果以下:
(4) ThreadGroup[name=g1,maxpri=8] Thread[A,9,g1]
一样可以看出,提高最大优先级的计划是失利的.我们只能降低一个线程组的最大优先级,而不能提高它.此外,注意线程A的优先级并未改变,并且它目前高于线程组的最大优先级.也就是说,线程组最大优先级的改变并不能对现有线程造成影响.
第五个操练试着将一个新线程设为最大优先级.以下所示:
(5) ThreadGroup[name=g1,maxpri=8] Thread[A,9,g1] Thread[B,8,g1]
因此,新线程不能变到比最大线程组优先级还要高的一级.
这个程序的默许线程优先级是6;若新建一个线程,那就是它的默许优先级,并且不会发生改变,除非对优先级举行了分外的处理.操练六将把线程组的最大优先级降至默许线程优先级以下,看看在这种情形下新建一个线程会发生什么事情:
(6) ThreadGroup[name=g1,maxpri=3] Thread[A,9,g1] Thread[B,8,g1] Thread[C,6,g1]
固然线程组目前的最大优先级是3,但仍旧用默许优先级6来成立新线程.所以,线程组的最大优先级不会影响默许优先级(事实上,仿佛没有办法可以设置新线程的默许优先级).
改变了优先级后,接下来试试将其降低一级,后果以下:
(7) ThreadGroup[name=g1,maxpri=3] Thread[A,9,g1] Thread[B,8,g1] Thread[C,3,g1]
因此,只有在试图改变优先级的时刻,才会逼迫服从线程组最大优先级的限制.
我们在(8)和(9)中举行了近似的试验.在这里,我们成立了一个新的线程组,名为g2,将其作为g1的一个子组,并改变了它的最大优先级.大家可以看到,g2的优先级无论若何都不大概高于g1:
(8) ThreadGroup[name=g2,maxpri=3] (9) ThreadGroup[name=g2,maxpri=3]
也要注意在g2成立的时刻,它会被自动设为g1的线程组最大优先级.
经过全部这些实行今后,整个线程组和线程系统城市被打印出来,以下所示:
所以由线程组的法则所限,一个子组的最大优先级在任什么时刻候都只能低于或等于它的父组的最大优先级.(10)ThreadGroup[name=system,maxpri=9] Thread[main,6,system] ThreadGroup[name=g1,maxpri=3] Thread[A,9,g1] Thread[B,8,g1] Thread[C,3,g1] ThreadGroup[name=g2,maxpri=3] Thread[0,6,g2] Thread[1,6,g2] Thread[2,6,g2] Thread[3,6,g2] Thread[4,6,g2]
本程序的最后一个部份演示了用于整组线程的办法.程序首先遍历整个线程树,并启动每一个还没有启动的线程.比方,system组随后会被挂起(暂停),最后被中止(固然用suspend()和stop()对整个线程组举行操作看起来仿佛很风趣,但应注意这些办法在Java 1.2里都是被“反对”的).但在挂起system组的同时,也挂起了main线程,并且整个程序城市关闭.所以永久不会到达让线程中止的那一步.实际上,假定真的中止了main线程,它会“掷”出一个ThreadDeath违例,所以我们普通不这样做.由于ThreadGroup是从Object担当的,此中包含了wait()办法,所以也能调用wait(秒数×1000),令程序暂停运行肆意秒数的时间.当然,事前必须在一个同步块里获得对象锁.
ThreadGroup类也供应了suspend()和resume()办法,所以能中止和启动整个线程组和它的全部线程,也能中止和启动它的子组,全部这些只需一个号令便可(再次提醒,suspend()和resume()都是Java 1.2所“反对”的).
从表面看,线程组仿佛有些让人摸不着头脑,但请注意我们很少需求直接利用它们.
以上是“java的线程组[Java编程]”的内容,如果你对以上该文章内容感兴趣,你可以看看七道奇为您推荐以下文章:
本文地址: | 与您的QQ/BBS好友分享! |
- ·上一篇文章:回想runnable
- ·下一篇文章:线程的优先级
- ·中查找“java的线程组”更多相关内容
- ·中查找“java的线程组”更多相关内容
评论内容只代表网友观点,与本站立场无关!
评论摘要(共 0 条,得分 0 分,平均 0 分)
查看完整评论