java并发 api里有个有趣的方法是把线程分组。这个方法允许我们按线程组作为一个单位来处理。例如,你有一些线程做着同样的任务,你想控制他们,无论多少线程还在运行,他们的状态会被一个call 中断。
java 提供 threadgroup 类来组织线程。 threadgroup 对象可以由 thread 对象组成和由另外的 threadgroup 对象组成,生成线程树结构。
在这个指南中, 我们将开发一个简单的例子来学习 threadgroup 对象。我们有 10 个随机时间休眠的线程 (例如,模拟搜索),然后当其中一个完成,就中断其余的。
<b>准备</b>
指南中的例子是使用eclipse ide 来实现的。如果你使用eclipse 或者其他的ide,例如netbeans, 打开并创建一个新的java项目。
怎么做呢<b>…</b>
按照这些步骤来实现下面的例子::
1. 首先,创建一个类名为 result。它会保存最先结束的线程的名字。声明一个 private string 属性名为 name 并提供相应的读值和设置值的方法。
2. 创建一个类名为 searchtask a并一定实现 runnable 接口。
<code>1</code>
<code>public</code> <code>class</code> <code>searchtask</code><code>implements</code> <code>runnable {</code>
3. 声明一个result类的 private 属性变量并实现和初始化这类属性的构造函数。
<code>private</code> <code>result result;</code>
<code>2</code>
<code>public</code> <code>searchtask(result result) {</code>
<code>3</code>
<code>this</code><code>.result=result;</code>
<code>4</code>
<code>}</code>
4. 实现run()方法。 它会调用dotask() 方法和等待它结束或者接收一个 interruptedexception 异常。 这方法会写信息表明开始,结束,或者线程中断。
<code>01</code>
<code>@override</code>
<code>02</code>
<code>public</code> <code>void</code> <code>run() {</code>
<code>03</code>
<code>string name=thread.currentthread().getname();</code>
<code>04</code>
<code>system.out.printf(</code><code>"thread %s: start\n"</code><code>,name);</code>
<code>05</code>
<code>try</code> <code>{</code>
<code>06</code>
<code>dotask();</code>
<code>07</code>
<code>result.setname(name);</code>
<code>08</code>
<code>}</code><code>catch</code> <code>(interruptedexception e) {</code>
<code>09</code>
<code>system.out.printf(</code><code>"thread %s: interrupted\n"</code><code>,name);</code>
<code>10</code>
<code>return</code><code>;</code>
<code>11</code>
<code>12</code>
<code>system.out.printf(</code><code>"thread %s: end\n"</code><code>,name);</code>
<code>13</code>
5. 实现 dotask() 方法。它会创建一个 random 对象生一个随机数字并用这个数字调用 sleep() 方法 。
<code>private</code> <code>void</code> <code>dotask()</code><code>throws</code> <code>interruptedexception {</code>
<code>random random=</code><code>new</code> <code>random((</code><code>new</code> <code>date()).gettime());</code>
<code>int</code> <code>value=(</code><code>int</code><code>)(random.nextdouble()*</code><code>100</code><code>);</code>
<code>system.out.printf(</code><code>"thread %s: %d\n"</code><code>,thread.currentthread(). getname(),value);</code>
<code>5</code>
<code>timeunit.seconds.sleep(value);</code>
<code>6</code>
6. 现在, 创建例子主类通过创建 main 类和实现 main() 方法.
<code>public</code> <code>class</code> <code>main {</code>
<code>public</code> <code>static</code> <code>void</code> <code>main(string[] args) {</code>
7. 首先, 创建一个 threadgroup 对象命名 searcher.
<code>threadgroup threadgroup =</code><code>new</code> <code>threadgroup(</code><code>"searcher"</code><code>);</code>
8. 然后, 创建 一个 searchtask 对象和 一个 result 对象。
<code>result result=</code><code>new</code> <code>result();</code>
<code>searchtask searchtask=</code><code>new</code> <code>searchtask(result);</code>
9. 现在, 使用searchtask对象创建 10个 thread o对象。当你调用thread 类的构造函数时,传递它作为threadgroup对象的第一个参数。
<code>for</code> <code>(</code><code>int</code> <code>i=</code><code>0</code><code>; i<</code><code>5</code><code>; i++) {</code>
<code>thread thread=</code><code>new</code> <code>thread(threadgroup, searchtask);</code>
<code>thread.start();</code>
<code>timeunit.seconds.sleep(</code><code>1</code><code>);</code>
<code>7</code>
<code>e.printstacktrace();</code>
<code>8</code>
<code>9</code>
10. 使用list() 方法写关于 threadgroup ob对象信息。
<code>system.out.printf(</code><code>"number of threads: %d\n"</code><code>,threadgroup. activecount());</code>
<code>system.out.printf(</code><code>"information about the thread group\n"</code><code>);</code>
<code>threadgroup.list();</code>
11. 使用 activecount() 和 enumerate() 方法来获取线程个数和与threadgroup对象关联的线程的列表。我们可以用这个方法来获取信息, 例如,每个线程状态。
<code>thread[] threads=</code><code>new</code> <code>thread[threadgroup.activecount()];</code>
<code>threadgroup.enumerate(threads);</code>
<code>for</code> <code>(</code><code>int</code> <code>i=</code><code>0</code><code>; i<threadgroup.activecount(); i++) {</code>
<code>system.out.printf(</code><code>"thread %s: %s\n"</code><code>,threads[i].getname(),threads[i].getstate());</code>
12. 调用 waitfinish()方法. 我们等下来实现这方法。它会等待threadgroup对象中的其中一个线程结束。
<code>waitfinish(threadgroup);</code>
13. 用interrupt() 方法中断组里的其他线程。
<code>threadgroup.interrupt();</code>
14. 实现 waitfinish() 方法. 它会使用 activecount() 方法来控制到最后一个线程。
<code>private</code> <code>static</code> <code>void</code> <code>waitfinish(threadgroup threadgroup) {</code>
<code>while</code> <code>(threadgroup.activecount()></code><code>9</code><code>) {</code>
15. 运行例子并查看结果。
<b>它是怎么工作的</b><b>…</b>
在下面的截图内, 你可以发现 list() 方法 的输出和当我们把每个线程对象的状态写入时候的输出, 请看截图:
threadgroup 类储存线程对象和其他有关联的 threadgroup 对象,所以它可以访问他们的所有信息 (例如,状态) 和全部成员的操作表现 (例如,中断)。
<b>更多</b><b>…</b>
threadgroup 类有很多方法. 查看 api 文档里的这些方法的详细说明。