一、并发编程
1、Fork/Join分支合并框架
Fork/Join它可以将一个大的任务拆分成多个子任务进行并行处理,最后将子任务结果合并成最后的计算结果,并进行输出。Fork/Join框架要完成两件事情:
Fork:把一个复杂任务进行分拆,大事化小
Join:把分拆任务的结果进行合并
RecursiveTask 递归任务:继承后可以实现递归(自己调自己)调用的任务。
@since 1.7public abstract class RecursiveTask<V> extends ForkJoinTask<V>RecursiveTask构造方法:
1.RecursiveTask()RecursiveTask方法:
1.protected abstract V compute():此任务执行的主要计算。
2.protected boolean exec():实现递归任务的执行约定。
3.V getRawResult():返回ForkJoinTask将返回的结果。join(),即使此任务异常完成,
或者如果未知此任务已完成,则为null。
4.protected void setRawResult(V value):强制返回给定的值作为结果。-----------------------------------------------------------------------
ForkJoinTask<V>
@since 1.7public abstract class ForkJoinTask<V> extends Object
implements Future<V>, SerializableForkJoinTask<V>构造方法:
1.ForkJoinTask()ForkJoinTask<V>常用方法:
1.ForkJoinTask<V> fork():安排异步执行此任务。
2.V get():如有必要,等待计算完成,然后检索其结果。
3.V join():完成计算后返回计算结果。-----------------------------------------------------------------------
ForkJoinPoolpublic class ForkJoinPool extends AbstractExecutorServiceForkJoinPool构造方法:
1.ForkJoinPool()ForkJoinPool常用方法:
1.void execute(ForkJoinTask<?> task):安排(异步)执行给定任务。
2.void execute(Runnable task):在将来的某个时间执行给定的命令。
3.<T> ForkJoinTask<T> submit(Callable<T> task):提交一个返回值的任务以供执行,
并返回一个表示任务挂起结果的未来。
4.<T> ForkJoinTask<T> submit(ForkJoinTask<T> task):提交要执行的ForkJoinTask。
5.ForkJoinTask<?> submit(Runnable task):提交可运行任务以执行,并返回表示该任务的未来。
6.<T> ForkJoinTask<T> submit(Runnable task, T result):提交可运行任务以执行,
并返回表示该任务的未来。
7.void shutdown():启动有序关机,执行以前提交的任务,但不接受新任务。
Fork/Join示例:
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.ForkJoinTask;
import java.util.concurrent.RecursiveTask;//求1+2+3+....100。需要拆分任务不超过10个数进行相加拆分
public class ForkJoinDemo {public static void main(String[] args) throws Exception {MyTask myTask = new MyTask(0,100);//创建分支合并池对象ForkJoinPool forkJoinPool = new ForkJoinPool();ForkJoinTask<Integer> forkJoinTask = forkJoinPool.submit(myTask);//获取最终合并之后结果Integer result = forkJoinTask.get();System.out.println(result);//关闭池对象forkJoinPool.shutdown();}
}@SuppressWarnings("serial")
class MyTask extends RecursiveTask<Integer>{private static final Integer VALUE = 10;private int begin;private int end;private int result;public MyTask(int begin, int end) {this.begin = begin;this.end = end;}@Overrideprotected Integer compute() {//判断if ((end-begin) <= VALUE) {for (int i = begin; i <= end; i++) {result = result + i;}}else {int middle = (begin+end)/2;//拆分左边MyTask task01 = new MyTask(begin, middle);//拆分右边MyTask task02 = new MyTask(middle+1, end);//调用方法拆分task01.fork();task02.fork();//合并结果result = task01.join() +task02.join();}return result;}
}
2、CompletableFuture异步回调
同步:
异步:
CompletableFuture异步回调示例:
import java.util.concurrent.CompletableFuture;public class CompletableFutureDemo {public static void main(String[] args) throws Exception {//同步调用CompletableFuture<Void> completableFuture1 = CompletableFuture.runAsync(()->{System.out.println(Thread.currentThread().getName() + " :completableFuture1");});completableFuture1.get();//异步调用CompletableFuture<Integer> completableFuture2 = CompletableFuture.supplyAsync(()->{System.out.println(Thread.currentThread().getName() + " :completableFuture2");return 1024;});completableFuture2.whenComplete((t,u)->{System.out.println("--t--"+t);//t:表示成功的返回值System.out.println("--u--"+u);//u:表示失败异常的信息}).get();//异步调用CompletableFuture<Integer> completableFuture3 = CompletableFuture.supplyAsync(()->{System.out.println(Thread.currentThread().getName() + " :completableFuture3");//模拟异常int i = 10/0;return 1024;});completableFuture3.whenComplete((t,u)->{System.out.println("--t--"+t);//t:表示成功的返回值System.out.println("--u--"+u);//u:表示失败异常的信息}).get();}
}
实际开发中一般不会用CompletableFuture异步回调。都会使用MQ消息队列的方式。
Java 并发编程(五)-线程池
每天⽤⼼记录⼀点点。内容也许不重要,但习惯很重要!
一个程序员最重要的能力是:写出高质量的代码!!
有道无术,术尚可求也,有术无道,止于术。
无论你是年轻还是年长,所有程序员都需要记住:时刻努力学习新技术,否则就会被时代抛弃!