线程组

问题的提出,我们经常会有几项的任务,这几项任务之间本身没有先后顺序关系,或者是协作来共同完成一个目标。这个时候,我们就希望能够把这几项任务并行进行运行以充分利用CPU,缩短运行时间,或者把大的任务分成小的任务,所有的小任务都完成时,再继续进行下一阶段的处理。 
这个时候就有一个问题了,因为一般的Java多线程都是互不相关的,也就是当这个任务在执行的时候,主线程也会执行,但是因为这个时候前面的任务还不一定执行完毕,所以,主线程继续向下执行是有问题的,因此我们就要主线程等待这些线程执行完毕后再向下执行。 
为此,封装了一个线程组的概念,一个线程组内可以包含N个线程,所有的线程运行完毕后,线程组才会结束,调用线程组的线程才会继续向下执行。 
首先看示例: 

?


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

public class NumberAdd extends AbstractProcessor {

    public static int sumValue;

    private static Object lockObject = new Object();

 

    public NumberAdd(String name) {

        super(name);

    }

 

    @Override

    protected void action() throws Exception {

        for (int i = 0; i < 1000; i++) {

            add();

            Thread.sleep(1);

        }

    }

 

    private static void add() {

        synchronized (lockObject) {

            sumValue++;

        }

    }

}

上面的程序是一个类,它用于把sumValue中的值增加1000。 
下面是测试用例 

?


1

2

3

4

5

6

7

8

9

10

11

public void testStart() {

        MultiThreadProcessor processors = new MultiThreadProcessor("number add");

        for (int i = 0; i < 10; i++) {

            processors.addProcessor(new NumberAdd("add" + i));

        }

        long startTime = System.currentTimeMillis();

        processors.start();

        long endTime = System.currentTimeMillis();

        logger.log(LogLevel.INFO, "执行时间:{}", endTime - startTime);

        assertEquals(10000, NumberAdd.sumValue);

    }

启动了10个线程来执行添加操作,因为每个线程添加1000,最终应该是添加30000才对。 
最终的执行结果: 

?


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

-0    [main] INFO   - 线程组<number add>运行开始,线程数10...

-5    [number add-add0] INFO   - 线程<number add-add0>运行开始...

-6    [number add-add4] INFO   - 线程<number add-add4>运行开始...

-6    [number add-add3] INFO   - 线程<number add-add3>运行开始...

-6    [number add-add1] INFO   - 线程<number add-add1>运行开始...

-6    [number add-add2] INFO   - 线程<number add-add2>运行开始...

-6    [number add-add7] INFO   - 线程<number add-add7>运行开始...

-7    [number add-add8] INFO   - 线程<number add-add8>运行开始...

-7    [number add-add5] INFO   - 线程<number add-add5>运行开始...

-7    [number add-add6] INFO   - 线程<number add-add6>运行开始...

-7    [number add-add9] INFO   - 线程<number add-add9>运行开始...

-1023 [number add-add6] INFO   - 线程<number add-add6>运行结束

-1023 [number add-add1] INFO   - 线程<number add-add1>运行结束

-1024 [number add-add9] INFO   - 线程<number add-add9>运行结束

-1024 [number add-add2] INFO   - 线程<number add-add2>运行结束

-1025 [number add-add5] INFO   - 线程<number add-add5>运行结束

-1029 [number add-add7] INFO   - 线程<number add-add7>运行结束

-1029 [number add-add4] INFO   - 线程<number add-add4>运行结束

-1030 [number add-add0] INFO   - 线程<number add-add0>运行结束

-1030 [number add-add3] INFO   - 线程<number add-add3>运行结束

-1031 [number add-add8] INFO   - 线程<number add-add8>运行结束

-1031 [main] INFO   - 线程组<number add>运行结束, 用时:1026ms

-1032 [main] INFO   -

并且测试用例也执行通过,说明最终的结果,确实是加了30000次。 
而且是在线程组执行完毕后,才执行的assertEquals语句。 
从此,写多线程协作就像写普通程序一样了。(注意是像,不是是,因为还是要注意冲突对象的同步问题的) 

时间: 2024-08-04 05:36:02

线程组的相关文章

多线程基础(七)GCD线程组+栅栏函数

1.GCD队列组 拦截通知和等待所有任务全部结束在继续往下执行|阻塞 需求:下载两张图片,等两张图片都下载完毕之后,合成图片(这个实例,复习的时候一定要凭空敲出代码练习,好记性不如烂键盘) <两种思路:1.线程组前两个异步函数加载url,最后在拦截函数notify合成 2.在一个子线程中就加载url获取数据,然后合成> 官方规定了,栅栏函数 只能用在调度并发队列中,不能使用在全局并发队列中

java的线程组

所有线程都隶属于一个线程组.那可以是一个默认线程组,亦可是一个创建线程时明确指定的组.在创建之初,线程被限制到一个组里,而且不能改变到一个不同的组.每个应用都至少有一个线程从属于系统线程组.若创建多个线程而不指定一个组,它们就会自动归属于系统线程组. 线程组也必须从属于其他线程组.必须在构建器里指定新线程组从属于哪个线程组.若在创建一个线程组的时候没有指定它的归属,则同样会自动成为系统线程组的一名属下.因此,一个应用程序中的所有线程组最终都会将系统线程组作为自己的"父". 之所以要提出

线程管理(十)线程组

线程组 Java并发 API里有个有趣的方法是把线程分组.这个方法允许我们按线程组作为一个单位来处理.例如,你有一些线程做着同样的任务,你想控制他们,无论多少线程还在运行,他们的状态会被一个call 中断. Java 提供 ThreadGroup 类来组织线程. ThreadGroup 对象可以由 Thread 对象组成和由另外的 ThreadGroup 对象组成,生成线程树结构. 在这个指南中, 我们将开发一个简单的例子来学习 ThreadGroup 对象.我们有 10 个随机时间休眠的线程

线程管理(十一)处理线程组内的不受控制异常

处理线程组内不受控制异常 对于编程语言来说,一个非常重要的事情是提供管理应用出错情况的机制.Java 语言, 作为最现代的编程语言,实现except基于异常的机制来管理出错情况,它提供很多种类来表示不同的错误.当检测到一个异常状况时,这些异常会被Java类们抛出.你也可以使用这些异常, 或者实现你自己的异常, 来管理你的类产生的错误. Java 也提供机制来捕捉和处理这些异常 .有些一定要被捕捉或者使用方法的throws句组再抛出,这些异常称为检查异常(checked exceptions).有

用GCD线程组与GCD信号量将异步线程转换为同步线程

有时候我们会碰到这样子的一种情形: 同时获取两个网络请求的数据,但是网络请求是异步的,我们需要获取到两个网络请求的数据之后才能够进行下一步的操作,这个时候,就是线程组与信号量的用武之地了. #import "ViewController.h" #import <AFNetworking.h> @interface ViewController () @end @implementation ViewController - (void)viewDidLoad { [supe

Java并发编程示例(十):线程组_java

对线程分组是Java并发API提供的一个有趣功能.我们可以将一组线程看成一个独立单元,并且可以随意操纵线程组中的线程对象.比如,可以控制一组线程来运行同样的任务,无需关心有多少线程还在运行,还可以使用一次中断调用中断所有线程的执行. Java提供了ThreadGroup类来控制一个线程组.一个线程组可以通过线程对象来创建,也可以由其他线程组来创建,生成一个树形结构的线程. 根据<Effective Java>的说明,不再建议使用ThreadGroup.建议使用Executor. --D瓜哥特此

java基础知识问答:线程组,死锁

问题描述 问题1:Thread的toString方法描述:返回该线程的字符串表示形式,包括线程名称.优先级和线程组.请问什么叫"线程组"?问题2:求一个死锁的demo,越简单越好 解决方案 线程组:http://caterpillar.onlyfun.net/Gossip/JavaGossip-V2/ThreadGroup.htm列锁例子:http://www.cnblogs.com/linjiqin/archive/2011/04/11/2013083.html希望对你有帮助解决方案

《Java程序员面试秘笈》—— 1.12 线程组中不可控异常的处理

1.12 线程组中不可控异常的处理 提供应用程序中对错误情景的管理,是编程语言很重要的一面.和几乎所有的现代编程语言一样,Java语言也实现了通过异常管理机制来处理错误情景,它提供了很多类来表示不同的错误.当错误情景发生时,Java类将抛出这些异常.你可以使用这些异常,或者实现自己的异常,来管理类中的错误. Java也提供了捕获和处理这些异常的机制.有的异常必须被捕获,或者必须使用方法的throws声明再次抛出,这类异常叫做非运行时异常.还有一类异常叫做运行时异常,它们不需要被捕获或者声明抛出.

[JAVA100例]063、线程群组

/** * <p>Title: 线程组群</p> * <p>Description: 通过线程组管理下面的多个线程.</p> * <p>Copyright: Copyright (c) 2003</p> * <p>Filename: myThreadgroup.java</p> * @version 1.0 */ public class myThreadgroup extends Thread { publi