java高并发设计(八)--并行框架fork/join

互联网一直在说和提到高并发,那什么是高并发,怎么处理高并发?也许每个人都有自己的见解和应对方法,但是总体思想应该及相同的,分而治之,单个服务不发满足时增加服务集群,集群无法满足时考虑拆分,同时选择合适的算法,最终达到解决高并发,但是什么样的级别才能算是高呢?不同的业务也许需求不一样,但是大致还都是相同的,我们最开始使用的处理要素是,200并发,200请求/秒,单机,并且后台也许会有不同的业务逻辑,也许会有其他的复杂计算,这个是根据不同的系统不同的业务而不同设计的。业务你的并发达不到这么高,根据数据的要求,你可能会想到异步处理,或者消息处理来增加并发数。所有的解决方案都不是相同的,只选择适合你们业务的解决方案。

言归正传,这里我们讲的是fork/join的并发处理框架,该框架是是在jdk1.7出现的,如果有人接触过hadoop中的mapreduce,思想是相同的。说起fork/join,我们首先看下该思想的执行操作线路图,这样可以更好的理解该并行计算框架。

上面的图解中有两个最大的世界,fork:将大任务拆分成小任务进行执行;join:将fork出来的小任务的执行结果进行合并,最终实现过程拆分结果合并的操作。

先上说明一些主要的类:ForkJoinTask:顶层设计类,主要是对任务的拆分合并的计算架构。该顶层类有两个核心子类,在java中也是主要继承这两个类来实现并行计算。RecursiveAction:从后缀也可以猜测出,该执行只是动作的执行,没有返回结果。RecursiveTask:执行任务,有返回值,并且是指定类型的返回结果。ForkJoinPool:任务执行线程池,根据自身算法实现线程的高度复用及任务优化。

下面从demo中解析:无返回值的操作

public class ObjectTest {
	
	public static void main(String[] args) throws InterruptedException {
		//创建执行线程池
		ForkJoinPool pool = new ForkJoinPool();
		//提交任务
		pool.submit(new ActionTest(0, 200));
		
		pool.awaitTermination(3, TimeUnit.SECONDS);
		pool.shutdown();
		
	}

}

//继承无返回值的任务
class ActionTest extends RecursiveAction {
	
	private static final int MAX = 50;
	
	private int start;
	private int end;
	public ActionTest(int start, int end) {
		this.start = start;
		this.end = end;
	}

	@Override
	protected void compute() {
		if ((end - start) < MAX) {
			System.out.println(Thread.currentThread().getName() + "--" + start + "==" + end);
		} else {
			int middle = (start + end) / 2;
			ActionTest up = new ActionTest(start, middle);
			ActionTest down = new ActionTest(middle, end);
			//继续拆分
			up.fork();
			down.fork();
		}
	}
}

源码中的提现:

public class ForkJoinPool extends AbstractExecutorService ,该源码中涉及到很多线程安全和线程池的概念,源码比较多,这里就不一一说明,后面有时间了会拿出来单独说明。

public abstract class RecursiveTask<V> extends ForkJoinTask<V> {
    private static final long serialVersionUID = 5232453952276485270L;

    /**
     * The result of the computation.
     */
    V result;

    /**
     * The main computation performed by this task.
     */
    protected abstract V compute();

    public final V getRawResult() {
        return result;
    }

    protected final void setRawResult(V value) {
        result = value;
    }

    /**
     * Implements execution conventions for RecursiveTask.
     */
    protected final boolean exec() {
        result = compute();
        return true;
    }
}

该源码很简单,只是对父类的继承,操作的结果是无返回值的,所以有两个方法直接操作返回,主要提供抽象的compute()方法供子类实现。

有返回值的demo:

public class ObjectTest {
	
	public static void main(String[] args) throws InterruptedException, ExecutionException {
		//创建执行线程池
		ForkJoinPool pool = new ForkJoinPool();
		//提交任务
		Future<Integer> futuer = pool.submit(new TaskTest(0, 200));
		System.out.println(futuer.get());
		pool.awaitTermination(3, TimeUnit.SECONDS);
		pool.shutdown();
		
	}

}

class TaskTest extends RecursiveTask<Integer> {
private static final int MAX = 50;
	
	private int start;
	private int end;
	public TaskTest(int start, int end) {
		this.start = start;
		this.end = end;
	}
	@Override
	protected Integer compute() {
		int sum = 0;
		if ((end - start) < MAX) {
			for (int i = start; i < end; i++) {
				sum += i;
			}
			return sum;
		} else {
			int middle = (start + end) / 2;
			TaskTest up = new TaskTest(start, middle);
			TaskTest down = new TaskTest(middle, end);
			//继续拆分
			up.fork();
			down.fork();
			return up.join() + down.join();
		}
	}
	
}

主要区别在继承的父类和返回值,提现在join方法上。

源码体现:

public abstract class RecursiveTask<V> extends ForkJoinTask<V> {
    private static final long serialVersionUID = 5232453952276485270L;

    /**
     * The result of the computation.
     */
    V result;

    /**
     * The main computation performed by this task.
     */
    protected abstract V compute();

    public final V getRawResult() {
        return result;
    }

    protected final void setRawResult(V value) {
        result = value;
    }

    /**
     * Implements execution conventions for RecursiveTask.
     */
    protected final boolean exec() {
        result = compute();
        return true;
    }

}

主要在返回值上的设置会获取

这里先做简单的演示,后面再做深层次的解析和分析

转载于:https://my.oschina.net/wangshuaixin/blog/823436

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值