1、Stream流式计算
package com.coding.stream;
import java.util.Arrays;
import java.util.List;
// 数据库、集合 : 存数据的
// Stream:计算和处理数据交给 Stream
public class StreamDemo {
/**
* 按条件用户筛选:
* 1、id 为偶数
* 2、年龄大于24
* 3、用户名大写 映射
* 4、用户名倒排序
* 5、输出一个用户
*
* 请你只用一行代码完成!
*/
public static void main(String[] args) {
User u1 = new User(1,"a",23);
User u2 = new User(2,"b",24);
User u3 = new User(3,"c",22);
User u4 = new User(4,"d",28);
User u5 = new User(6,"e",26);
// 存储
List<User> users = Arrays.asList(u1, u2, u3, u4, u5);
// 计算等操作交给流
// forEach(消费者类型接口)
users.stream()
.filter(u->{return u.getId()%2==0;})
.filter(u->{return u.getAge()>24;})
.map(u->{return u.getName().toUpperCase();})
.sorted((o1,o2)->{return o2.compareTo(o1);})
.limit(1)
.forEach(System.out::println);
}
}
2、分支合并
什么是 forkjoin
MapReduce:input->split->map->reduce->output
主要就是两步:
1、任务拆分
2、结果合并
前提:forkjoin 一定是用在大数据量的情况下
工作原理:工作窃取
底层维护的是一个双端队列;
好处:效率高
坏处:产生资源争夺
测试一下Forkjoin
package com.coding.forkjoin;
import java.util.concurrent.RecursiveTask;
// 求和
public class ForkJoinWork extends RecursiveTask<Long> {
private Long start;
private Long end;
private static final Long tempLong = 10000L; // 临界值:只要超过了这个值 ForkJoin效率就会更好!
public ForkJoinWork(Long start, Long end) {
this.start = start;
this.end = end;
}
// 计算方法
@Override
protected Long compute() {
// 临界值判断
if ((end-start)<=tempLong){
Long sum = 0L;
for (Long i = start; i <= end ; i++) {
sum += i;
}
return sum;
}else { // 第二种方式
long middle = (end + start) / 2;
ForkJoinWork right = new ForkJoinWork(start,middle);
right.fork(); // 压入线程队列
ForkJoinWork left = new ForkJoinWork(middle+1,end);
left.fork(); // 压入线程队列
// 获得结果 join 会阻塞等待结果
return right.join() + left.join();
}
}
}
package com.coding.forkjoin;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.ForkJoinTask;
import java.util.stream.LongStream;
// 技术没有高低之分,只有使用技术的人有高低之别
// 因为场景适合,所以使用!
public class MyTest {
public static void main(String[] args) throws ExecutionException, InterruptedException {
test1(); // times:154 r=>500000000500000000
test2(); // times:10235 r=>500000000500000000
test3(); // times:15189 r=>500000000500000000
}
// 普通的 3000
private static void test3() {
Long sum = 0L;
long start = System.currentTimeMillis();
for (Long i = 0L; i <= 2L ; i++) {
sum += i;
}
long end = System.currentTimeMillis();
System.out.println("times:"+(end-start)+" r=>"+sum);
}
// forkjoin 6000
private static void test2() throws ExecutionException, InterruptedException {
long start = System.currentTimeMillis();
ForkJoinPool forkJoinPool = new ForkJoinPool();
ForkJoinWork forkJoinWork = new ForkJoinWork(0L, 2L);
ForkJoinTask<Long> submit = forkJoinPool.submit(forkJoinWork);
Long sum = submit.get();
long end = System.currentTimeMillis();
System.out.println("times:"+(end-start)+" r=>"+sum);
}
// 并行流计算 9000 流计算
private static void test1() {
long start = System.currentTimeMillis();
// 流计算
long sum = LongStream.rangeClosed(0L, 2L).parallel().reduce(0, Long::sum);
long end = System.currentTimeMillis();
System.out.println("times:"+(end-start)+" r=>"+sum);
}
}
3、异步回调
Future
CompletableFuture
代码测试
package com.coding.future;
import java.util.TreeMap;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
public class CompletableFutureDemo {
public static void main(String[] args) throws ExecutionException, InterruptedException {
// 没有返回值,好比多线程,功能更强大!
// CompletableFuture<Void> completableFuture = CompletableFuture.runAsync(() -> {
// try {
// TimeUnit.SECONDS.sleep(2);
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
// System.out.println(Thread.currentThread().getName() + "没有返回值!");
// });
// System.out.println("111111");
// completableFuture.get();
// 有返回值
// 任务
CompletableFuture<Integer> uCompletableFuture = CompletableFuture.supplyAsync(() -> {
System.out.println(Thread.currentThread().getName()+"=>supplyAsync!");
int i = 10/0;
return 1024;
});
System.out.println(uCompletableFuture.whenComplete((t, u) -> { // 成功
System.out.println("t=>" + t); // 正确结果
System.out.println("u=>" + u); // 错误信息
}).exceptionally(e -> { // 失败,如果错误就返回错误的结果!
System.out.println("e:" + e.getMessage());
return 500;
}).get());
}
}