Fork/Join框架

Fork/Join框架

java7提供的一个用于并行执行的框架,是一个把大任务拆分成若干个小任务,然后把小任务的结果汇总得到大任务结果的框架。
  1. 工作窃取算法
    • 定义:指某个线程从其他队列里窃取任务来执行。
      因为fork会将大任务分成若干个小的任务,然后为了减少线程之间的竞争,会将这些子任务放入到不同的队列中,并为每个队列创建一个单独的线程来执行。当某线程的队列任务执行完时,可以去其他队列里窃取任务来处理。
      为了减少窃取任务线程和被窃取任务的线程之间的线程,任务队列一般采用双端队列的设计,被窃取任务线程从队首提取任务,而窃取任务的线程从队尾提取任务。
    • 优点:充分利用线程的并行计算,减少线程之间的竞争
    • 缺点:某些情况下还是会存在线程竞争,比如,队列里只有一个任务的时候。并且,因为创建多个线程和多个双端队列,所以资源开销比较大。
  2. Fork/Join框架的设计
    设计步骤:
    1. 任务分割:利用Fork类来将大任务迭代切分成足够小的子任务。
    2. 执行子任务并合并结果:分割后的子任务分别存储在双端队列的头部,对应线程分别从队列里提取任务并执行。执行完的结果统一放置在一个队列里。启动一个线程,从该队列里提取数据并进行合并。
    设计实现:
    1. ForkJoinTask类:ForkJoin任务,通常情况下通过继承该类的子类RecursiveAction(没有返回结果的任务)和RecursiveTask(用于有返回结果的任务)来创建一个ForkJoin任务,来提供在任务中执行fork()和join()操作的机制。ForkJoinTask需要实现compute()方法,在该方法里需要对人物进行判断分割和计算合并。
    2. ForkJoinPool:ForkJoinTask任务需要通过ForkJoinPool来执行。该ForkJoinPool是由ForkJoinTask数组和ForkJoinWorkerThread数组组成,前者负责存放程序提交给ForkJoinPool的任务,而后者负责执行这些任务。
    实现原理:
    1. ForkJoinTask的fork()方法:当我们调用该方法时,程序会调用ForkJoinWorkerThread的pushTask方法异步地执行这个任务,然后立即返回结果。
      pushTask方法经当前任务存放在ForkJoinTask数组里,然后调用ForkJoinPool的signalWork()方法来唤醒或者创建一个工作线程来执行任务。
    2. ForkJoinTask的join()方法:主要的作用就是阻塞当前线程并等待获取结果。它首先调用doJoin()方法来得到当前任务的状态来判断返回什么结果。任务状态有四种:已完成Normal,被取消Cancelled,信号Signal和出现异常Exception。
  3. Fork/Join框架的异常处理
    join方法在处理的时候:首先查看任务的状态,如果执行完成,则直接返回任务状态;如果没有执行完,则从任务数组里取出任务并执行。如果任务顺利执行完成,则设置任务状态为NORMAL,如果出现异常,则记录异常,并将任务状态设置为EXCEPTIONAL。
    因为ForkJoinTask执行时候抛出的异常不能在主线程中捕获,因此提供了isCompletedAbnormally()方法来检查任务是否已经抛出异常或者被取消:
    if(task.isCompletedAbnormally())
    {
        System.out.println(task.getException());
    }
    

并且通过getException()方法获取异常,如果没有处理完成或者正在处理,返回null,如果已经被取消,返回CancellationException。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值