-
目录
速度更快 - 代码更少Lambda
- 强大的Stream API
- 便于并发
- 最大化减少空指针Optinal
oracle-sun Hotspot
oracle JRocket
IBM j9 jvm
taobao taobao jvm
永久区 PremGen 没有了 PremGenSize MaxPremGenSize | |||
MetaSpace 元空间 使用物理内存 MetaspaceSize MaxMetaspaceSize |
四大内置函数式接口
Consumer<T>接口:消费型接口:
Supplier<T>接口:供给型接口:
Function<T,R>:函数型接口:
Predicate<T>:断言型接口:
package 新特性;
/**
* java8 内置的四大核心函数式接口
*
* Consumer<T> : 消费型接口
* void accept(T t);
*
* Supplier<T> : 供给型接口
* T get();
*
* Function<T,R> : 函数型接口
* R apply(T t);
*
* Predicate<T> : 断言型接口
* Boolean test(T t)
*
*/
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Supplier;
import org.junit.Test;
public class testLambda3 {
// Consumer<T> 消费型接口
@Test
public void test1() {
happy(10000,(s)->System.out.println("消费"+s));
}
public void happy(double Money,Consumer<Double> t) {
t.accept(Money);
}
//Supplier<T> 供给型接口
@Test
public void test2() {
List<Integer> aa= getNumList(10,()-> (int)(Math.random() * 100));
for (Integer integer : aa) {
System.out.println(integer);
}
}
//产生指定的整数
public List<Integer> getNumList(int num,Supplier<Integer> s){
List<Integer> list = new ArrayList<>();
for (int i = 0; i < num; i++) {
list.add(s.get());
}
return list;
}
// Function<T,R> : 函数型接口
@Test
public void test3() {
String ss = strHandler(" \t\twww111 ",(str)-> str.trim());
System.out.println(ss);
}
//需求:用于处理字符串
public String strHandler(String str,Function<String, String> fun) {
return fun.apply(str);
}
// Predicate<T> : 断言型接口
@Test
public void test4() {
List<String> strlist = Arrays.asList("www","ssss","ssssssss","tttt");
List<String> xx =filterStr(strlist,(s)->s.length()>=4);
for (String string : xx) {
System.out.println(string);
}
}
public List<String> filterStr(List<String> list,Predicate<String> pre){
List<String> strlist = new ArrayList<>();
for (String string : list) {
if(pre.test(string)) {
strlist.add(string);
}
}
return strlist;
}
}
方法引用 及用到的对象Employee 类
package 新特性;
public class Employee {
private Integer age;
private String name;
private Double salary;
private Status status;
public Employee() {
super();
}
public Employee(int age, String name, double salary) {
this.age = age;
this.name = name;
this.salary = salary;
}
public Employee(Integer age, String name, double salary, Status status) {
this.age = age;
this.name = name;
this.salary = salary;
this.status = status;
}
public Employee(int age) {
this.age = age;
}
public Employee(int age, String name) {
this.age = age;
this.name = name;
}
@Override
public String toString() {
return "Employee [age=" + age + ", name=" + name + ", salary=" + salary + ", status=" + status + "]";
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Double getSalary() {
return salary;
}
public void setSalary(Double salary) {
this.salary = salary;
}
public Status getStatus() {
return status;
}
public void setStatus(Status status) {
this.status = status;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + age;
result = prime * result + ((name == null) ? 0 : name.hashCode());
long temp;
temp = Double.doubleToLongBits(salary);
result = prime * result + (int) (temp ^ (temp >>> 32));
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Employee other = (Employee) obj;
if (age != other.age)
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
if (Double.doubleToLongBits(salary) != Double.doubleToLongBits(other.salary))
return false;
return true;
}
public enum Status{
FREE,BUSY,VOCATION
}
}
package 新特性;
import java.util.Comparator;
import java.util.function.BiFunction;
import java.util.function.BiPredicate;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Supplier;
import org.junit.Test;
/**
* 方法引用:若Lambda 体中的内容有方法已经实现了,我们可以使用"方法引用"
* (可以理解为方法引用是Lambda 表达式的另一种表现形式)
*
* 注意:需要实现的抽象方法的参数及返回值类型与引用的方法的参数及返回值类型必须保持一致
*
* 主要有3种语法格式
*
* 对象::实例方法名
*
* 类::静态方法名
*
* 类::实例方法名
*
* 二、构造器引用
* ClassName :: new
* 注意:需要调用的构造器的参数与函数式接口中抽象方法的参数列表保持一致
*
*
* 三、数组引用
*
* Type::new
*
* @author wangqiangac
* @verion NCC-1.0
* @since 2021-09-07 11:04:13
*/
public class testLambda4 {
//数组引用
@Test
public void test7() {
Function<Integer, String[]> fun = (x)->new String[x];
String[] ss = fun.apply(10);
Function<Integer, String[]> fun2 = String[]::new;
String[] ss2 = fun2.apply(20);
System.out.println(ss2.length);
}
//构造器引用
@Test
public void test() {
Supplier<Employee> sup = ()-> new Employee();
sup.get();
//构造器引用
Supplier<Employee> sup2 = Employee::new;
Function<Integer, Employee> fun = (x)->new Employee(x);
Function<Integer, Employee> fun2 = Employee::new;
Employee emp = fun2.apply(101);
System.out.println(emp);
BiFunction<Integer, String, Employee> bf = Employee::new;
}
//对象::实例方法名
@Test
public void test1() {
Consumer<String> con = (s)->System.out.println(s);
Consumer<String> con1 = System.out::println;
con1.accept("sssssssssssssccc");
}
//对象::实例方法名
@Test
public void test2() {
Employee emp = new Employee(15,"wq",1231212);
Supplier<String> sup = ()->emp.getName();
System.out.println(sup.get());
Supplier<Integer> sup2 = emp::getAge;
System.out.println(sup2.get());
}
//类::静态方法名
@Test
public void test3() {
Comparator<Integer> com = (x,y)-> Integer.compare(x, y);
Comparator<Integer> com1 = Integer::compare;
}
//类::实例方法名
@Test
public void test4() {
BiPredicate<String, String> bp = (x,y)->x.equals(y);
//如果说第一个参数是实例方法的调用者 第二个参数是这个方法的参数时 就可以使用
BiPredicate<String, String> bp1 = String::equals;
}
}
Stream API JUC+NIO
创建流
package 新特性;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Stream;
import org.junit.Test;
/**
* 一、Stream的三个步奏操作
* 1.创建Stream
* 2.中间操作
* 3.终止操作(中断操作)
* @author wangqiangac
* @verion NCC-1.0
* @since 2021-09-07 16:42:06
*/
public class TestStreamAPI {
//创建Stream
@Test
public void test() {
//1.可以通过Collection 系列集合提供的stream() 串行流 或 parallelStream() 并行流
List<String> list = new ArrayList<>();
Stream<String> stream1 = list.stream();
//2.通过Arrays中的静态方法stream()获取数组流
Stream<String> stream2 = Arrays.stream(new String[10]);
//3.通过Stream类中的静态方法of()
Stream<String> stream3 = Stream.of("aa","xx","ll");
//4.创建无限流
//迭代
// Stream.iterate(0, (x)->x+2).forEach(System.out::println);
Stream.iterate(0, (x)->x+2).limit(10).forEach(System.out::println);
//生成
Stream.generate(()->Math.random()).limit(5).forEach(System.out::println);
}
}
map映射中间操作
package 新特性;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.stream.Stream;
import org.junit.Test;
/**
* 一、Stream的三个步奏操作
* 1.创建Stream
* 2.中间操作 --不会有任何结果
* 3.终止操作(中断操作)
* @author wangqiangac
* @verion NCC-1.0
* @since 2021-09-07 16:42:06
*/
public class TestLambdaAPI1 {
List<Employee> list = Arrays.asList(
new Employee(18,"哈市卡",8888),
new Employee(19,"斧王",16000),
new Employee(16,"剑圣",10000),
new Employee(33,"蓝胖",21000),
new Employee(32,"火枪",25000),
new Employee(45,"美杜莎",19000),
new Employee(45,"美杜莎",19000),
new Employee(45,"美杜莎",19000),
new Employee(59,"幽鬼",3500));
/**
* 中间操作
* 筛选与切片
* filter-接受Lambda,从流中排出某些元素
* limit(n)-截断流,使其元素不超过给定数量
* skip(n)-跳过元素,返回一个扔掉了前n个元素的流,若流中元素不足n个,则返回一个空流,与limit互补
* distinct-筛选,通过流所生成元素的hashCode()和equals()去除重复元素
*/
@Test
public void test() {
/**
* Stream中间操作
* 内部迭代--迭代操作由Stream API完成
* 多个中间操作可以连接起来形成一个流水线,除非流水线上触发终止操作,否则中间操作不会执行任何的处理,而在终止操作时一次行全部处理,称为"惰性求值" "延迟加载"
*/
list.stream().filter((e)->{
System.out.println("中间操作");
return e.getAge()>35;
}).forEach(System.out::println);
}
//外部迭代
@Test
public void test1() {
Iterator<Employee> it = list.iterator();
while(it.hasNext()) {
System.out.println(it.next());
}
}
@Test
public void test2() {
list.stream().filter((e)->e.getSalary()>5000).limit(2).forEach(System.out::println);
}
//短路 && || 可以提高效率
@Test
public void test3() {
list.stream().filter((e)->{
System.out.println("短路!");
return e.getSalary()>5000;
}).limit(2).forEach(System.out::println);
}
//要想去重
@Test
public void test4() {
list.stream().filter((e)->{
System.out.println("短路!");
return e.getSalary()>5000;
}).skip(2).distinct().forEach(System.out::println);
}
/**
* 映射
* map-接受lambda,将元素转换成其他形式或提取信息,接收一个函数作为参数,该函数会被应用到每个元素上,并将其映射成一个新的元素
* flatMap-接受一个函数作为参数,将流中的每个值都换成另一个流,然后把所有流连接成一个流
*/
@Test
public void test5() {
List<String> list1 = Arrays.asList("AAA","BBB","CCCC","DDD");
list1.stream().map((s)->s.toLowerCase()).forEach(System.out::println);
list.stream().map((e)->e.getName()).forEach(System.out::println);
//流中流
Stream<Stream<Character>> stream = list1.stream().map(TestLambdaAPI1::filterCharacter);
stream.forEach(sm->{
sm.forEach(System.out::println);
});
//flatmap 扁平化 集合的addAll也是扁平化
list1.stream().flatMap((str)->{
List<Character> list = new ArrayList<>();
for (Character character : str.toCharArray()) {
list.add(character);
}
return list.stream();
}).forEach(System.out::println);;
}
public static Stream<Character> filterCharacter(String str){
List<Character> list = new ArrayList<>();
for (Character character : str.toCharArray()) {
list.add(character);
}
return list.stream();
}
/**
* sorted()--自然排序
* sorted(Comparator com)--定制排序
*/
@Test
public void test6() {
List<String> list3 = Arrays.asList("ccc","ddd","aaa","eee");
list3.stream().sorted().forEach(System.out::println);
list.stream().sorted((e1,e2)->{
if(e1.getAge()== e2.getAge()) {
return e1.getName().compareTo(e2.getName());
}else {
return e1.getAge().compareTo(e2.getAge());
}
}).forEach(System.out::println);;
}
}
终止操作
* 查找与匹配
* allMatch--检查是否匹配所有元素
* anyMatch--检查是否至少有一个元素匹配
* noneMatch--检查是否满意匹配所有元素
* findFirst--返回第一个元素
* findAny--返回当前流中的任意元素
* count--返回流中的总个数
* max--返回流中的最大值
* min--返回流中的最小值*
* .归约
* reduce(T identity,BinaryOperator) 可以将流中数据反复结合起来,得到一个值
*
* 收集
*
* collect--将流转换为其他形式。接受一个collector接口的实现,用于给stream中的元素做汇总的方法
package 新特性;
import java.util.Arrays;
import java.util.DoubleSummaryStatistics;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
import org.junit.Test;
import 新特性.Employee.Status;
/**
* 终止操作
*
* 查找与匹配
* allMatch--检查是否匹配所有元素
* anyMatch--检查是否至少有一个元素匹配
* noneMatch--检查是否满意匹配所有元素
* findFirst--返回第一个元素
* findAny--返回当前流中的任意元素
* count--返回流中的总个数
* max--返回流中的最大值
* min--返回流中的最小值
*
* .归约
* reduce(T identity,BinaryOperator) 可以将流中数据反复结合起来,得到一个值
*
* 收集
*
* collect--将流转换为其他形式。接受一个collector接口的实现,用于给stream中的元素做汇总的方法
*
* @author wangqiangac
* @verion NCC-1.0
* @since 2021-09-08 16:07:48
*/
public class testLamdaAPI2 {
List<Employee> list = Arrays.asList(
new Employee(18,"哈市卡",8888,Status.FREE),
new Employee(19,"斧王",16000,Status.BUSY),
new Employee(16,"剑圣",10000,Status.VOCATION),
new Employee(33,"蓝胖",21000,Status.BUSY),
new Employee(33,"蓝胖",21000,Status.BUSY),
new Employee(32,"火枪",25000,Status.FREE)
);
@Test
public void test() {
Boolean b1 = list.stream().allMatch((e)->e.getStatus().equals(Status.BUSY));
System.out.println(b1);
Boolean b2 = list.stream().anyMatch((e)->e.getStatus().equals(Status.BUSY));
System.out.println(b2);
Boolean b3 = list.stream().noneMatch((e)->e.getStatus().equals(Status.BUSY));
System.out.println(b3);
Optional<Employee> op = list.stream().sorted((e1,e2)->-Double.compare(e1.getSalary(), e2.getSalary())).findFirst();
System.out.println(op.get());
//找到free的任意一个 parallelStream并行流 多线程找
Optional<Employee> op1 =list.parallelStream().filter((e)->e.getStatus().equals(Status.FREE)).findAny();
System.out.println(op1.get());
System.out.println(list.stream().count());
Optional<Employee> op2 =list.stream().max((e1,e2)->Double.compare(e1.getSalary(), e2.getSalary()));
System.out.println(op2.get());
Optional<Double> op3 =list.stream().map((e)->e.getSalary()).min(Double::compare);
System.out.println(op3.get());
}
//reduce(T identity,BinaryOperator) 可以将流中数据反复结合起来,得到一个值
@Test
public void test1() {
List<Integer> list1 = Arrays.asList(2,3,5,44,33,222,1);
Integer sum = list1.stream().reduce(0, (x,y)->x+y);
System.out.println(sum);
//可能为空的才封装到Optional
/**
* map-reduce的连接通常称为map-reduce模式,因Google用它来进行网络搜索而出名
*/
Optional<Double> op= list.stream().map(Employee::getSalary).reduce(Double::sum);
System.out.println(op.get());
}
//收集
@Test
public void test2() {
List<String> l1 = list.stream().map((e)->e.getName()).collect(Collectors.toList());
l1.forEach(System.out::println);
Set<String> s1 =list.stream().map((e)->e.getName()).collect(Collectors.toSet());
s1.forEach(System.out::println);
System.out.println("--------------------");
HashSet<String> hs = list.stream().map((e)->e.getName()).collect(Collectors.toCollection(HashSet::new));
hs.forEach(System.out::println);
System.out.println("---------总数-----------");
Long count = list.stream().collect(Collectors.counting());
System.out.println(count);
System.out.println("---------平均值-----------");
Double averageSalary= list.stream().collect(Collectors.averagingDouble(Employee::getSalary));
System.out.println(averageSalary);
System.out.println("---------总和-----------");
Double sum= list.stream().collect(Collectors.summingDouble(Employee::getSalary));
System.out.println(sum);
System.out.println("---------最大值----------");
Optional<Employee> sum1= list.stream().collect(Collectors.maxBy((e1,e2)->Double.compare(e1.getSalary(), e2.getSalary())));
System.out.println(sum1.get());
System.out.println("---------最小值----------");
Optional<Double> sum2= list.stream().map(e->e.getSalary()).collect(Collectors.minBy(Double::compare));
System.out.println(sum2.get());
}
//收集 分组
@Test
public void test3() {
Map<Status, List<Employee>> map =list.stream().collect(Collectors.groupingBy(Employee::getStatus));
System.out.println(map);
}
//收集 多级分组
@Test
public void test4() {
Map<Status,Map<String,List<Employee>>> map = list.stream().collect(Collectors.groupingBy(e->e.getStatus(),Collectors.groupingBy(s-> {
if(s.getAge()<=35) {
return "青年";
}else {
return "中年";
}
})));
System.out.println(map);
}
//收集 分区
@Test
public void test5() {
Map<Boolean,List<Employee>> map = list.stream().collect(Collectors.partitioningBy((e)->e.getSalary()>10000));
System.out.println(map);
}
@Test
public void test6() {
DoubleSummaryStatistics dss = list.stream().collect(Collectors.summarizingDouble((e)->e.getSalary()));
System.out.println(dss.getAverage());
System.out.println(dss.getCount());
System.out.println(dss.getMax());
System.out.println(dss.getMin());
System.out.println(dss.getSum());
}
@Test
public void test8() {
String s = list.stream().map(Employee::getName).collect(Collectors.joining(",","===","@@@"));
System.out.println(s);
}
}
Stream 练习
package 新特性;
/**
* Stream 练习
* @author wangqiangac
* @verion NCC-1.0
* @since 2021-09-09 14:20:26
*/
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
import org.junit.Test;
import 新特性.Employee.Status;
public class TestStramAPI3 {
List<Employee> list = Arrays.asList(
new Employee(18,"哈市卡",8888,Status.FREE),
new Employee(19,"斧王",16000,Status.BUSY),
new Employee(16,"剑圣",10000,Status.VOCATION),
new Employee(33,"蓝胖",21000,Status.BUSY),
new Employee(33,"蓝胖",21000,Status.BUSY),
new Employee(32,"火枪",25000,Status.FREE)
);
/**
* 给定一个数组列表,返回一个有每个数的平方的列表
* 给定【1,2,3,4,5】 返回【1,3,9,16,25】
*/
@Test
public void test() {
Integer[] ints = new Integer[] {1,2,3,4,5};
List<Integer> l = Arrays.stream(ints).map((x)->x*x).collect(Collectors.toList());
System.out.println(l);
}
/**
* 用map和reduce方法数一数流中有多少个Employee
*/
@Test
public void test1() {
Optional<Integer> op = list.stream().map(e->1).reduce(Integer::sum);
System.out.println(op.get());
}
}
练习2
package 新特性;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.junit.Before;
import org.junit.Test;
public class TestTransaction {
List<Transaction> transaction;
@Before
public void before() {
transaction = Arrays.asList(new Transaction(new Trader("斧王", "郑州"), 2020, 20000000),
new Transaction(new Trader("蓝胖", "重庆"), 2021, 50000000),
new Transaction(new Trader("剑圣", "成都"), 2020, 66666666),
new Transaction(new Trader("哈市卡", "武汉"), 2020, 99999),
new Transaction(new Trader("火枪", "西安"), 2021, 55512245),
new Transaction(new Trader("幻刺", "焦作"), 2020, 888888888),
new Transaction(new Trader("wWwss", "焦作"), 2020, 454524545),
new Transaction(new Trader("xxchf", "焦作"), 2020, 45678225)
);
}
// 找出2020年发生的所有交易,并按照交易额排序
@Test
public void test() {
List<Transaction> s = transaction.stream().filter(e -> e.getYear() == 2020)
.sorted((o1, o2) -> Integer.compare(o1.getValue(), o2.getValue())).collect(Collectors.toList());
System.out.println(s);
}
// 交易员都在哪些不同的城市工作
@Test
public void test1() {
List<String> s = transaction.stream().map(t->t.getTrader().getCity()).distinct().collect(Collectors.toList());
System.out.println(s);
}
// 查找所有来自焦作的交易员并按照姓名排序
@Test
public void test2() {
List<String> s = transaction.stream()
.filter(t->t.getTrader().getCity().equals("焦作"))
.distinct()
.map(t->t.getTrader().getName())
.sorted((t1,t2)->-t1.compareTo(t2))
.collect(Collectors.toList());
System.out.println(s);
}
// 返回所有交易员的姓名字符串,按照字母排序
@Test
public void test3() {
List<String> collect = transaction.stream().map(t->t.getTrader().getName()).sorted().collect(Collectors.toList());
System.out.println(collect);
String reduce = transaction.stream().map(t->t.getTrader().getName()).sorted().reduce("", String::concat);
System.out.println(reduce);
//获取所有名称然后将名称拆分成字符再排序 flatMap 扁平化处理 流中流
List<String> collect2 = transaction.stream()
.map(t->t.getTrader().getName())
.flatMap(TestTransaction::filterCharacter)
.sorted((o1,o2)-> o1.compareToIgnoreCase(o2))
.collect(Collectors.toList());
System.out.println(collect2);
}
public static Stream<String> filterCharacter(String str){
List<String> list = new ArrayList<>();
for (Character character : str.toCharArray()) {
list.add(character.toString());
}
return list.stream();
}
// 交易员有没有在重庆工作
@Test
public void test4() {
Boolean c = transaction.stream().anyMatch(s->s.getTrader().getCity().equals("重庆"));
System.out.println(c);
}
// 返回生活在焦作的所有交易员的交易额
@Test
public void test5() {
Integer reduce = transaction.stream()
.filter(t->t.getTrader().getCity().equals("焦作"))
.map(Transaction::getValue)
.reduce(0,(x,y)->x+y);
System.out.println(reduce);
}
// 返回最高的交易额
@Test
public void test6() {
Optional<Integer> max = transaction.stream().map(t->t.getValue()).max((o1,o2)->Integer.compare(o1,o2));
System.out.println(max.get());
}
// 返回最小的交易额
@Test
public void test7() {
Optional<Integer> min = transaction.stream().map(t->t.getValue()).min(Integer::compare);
System.out.println(min.get());
}
}
Trader对象类
package 新特性;
public class Trader {
private String name;
private String city;
public Trader(String name, String city) {
this.name = name;
this.city = city;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
@Override
public String toString() {
return "Trader [name=" + name + ", city=" + city + "]";
}
}
Transaction对象类
package 新特性;
public class Transaction {
private Trader trader;
private int year;
private int value;
public Transaction(Trader trader, int year, int value) {
this.trader = trader;
this.year = year;
this.value = value;
}
public Trader getTrader() {
return trader;
}
public void setTrader(Trader trader) {
this.trader = trader;
}
public int getYear() {
return year;
}
public void setYear(int year) {
this.year = year;
}
public int getValue() {
return value;
}
public void setValue(int value) {
this.value = value;
}
@Override
public String toString() {
return "Transaction [trader=" + trader + ", year=" + year + ", value=" + value + "]";
}
}
并行流与顺序流
并行流就是把一个内容分成分成多个数据块,并用不同的线程分别处理每个数据块的流
Java 8 将并行进行了优化,我们可以很容易的对数据进行并行操作,Stream.API可以声明性的通过parallel()与sequential()在并行流与顺序流之间进行切换。
多线程会发生阻塞,当某一个线程发生阻塞(线程什么时候执行是按照cpu分配的时间决定)
效率高---工作窃取模式
JDL1.7 Fork/join
package 新特性;
import java.util.concurrent.RecursiveTask;
/**
* RecursiveTask<V> 有返回值
* RecursiveAction 没有返回值
* @author wangqiangac
* @verion NCC-1.0
* @since 2021-09-10 10:02:59
*/
public class ForkJoinCalculate extends RecursiveTask<Long>{
private static final long serialVersionUID = 1L;
private Long start;
private Long end;
private static final long THRESHOLD = 10000;
public ForkJoinCalculate(Long start, Long end) {
this.start = start;
this.end = end;
}
@Override
protected Long compute() {
Long length = end - start;
if(length>THRESHOLD) {
long sum = 0;
for (Long i = start; i < end; i++) {
sum = sum + i;
}
return sum;
}else {
long middle = (start+end)/2;
ForkJoinCalculate left = new ForkJoinCalculate(start,middle);
left.fork();//拆分子任务,同时压入线程队列
ForkJoinCalculate right = new ForkJoinCalculate(middle+1,end);
right.fork();//拆分子任务,同时压入线程队列
return left.join()+right.join();
}
}
}
单线程、jdk1.7 fork/join框架 jdk 1.8并行流 parallel() 耗时对比
package 新特性;
import java.time.Duration;
import java.time.Instant;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.ForkJoinTask;
import java.util.stream.LongStream;
import org.junit.Test;
/**
*
* @author wangqiangac
* @verion NCC-1.0
* @since 2021-09-10 10:30:53
*/
public class ForkJoinTest {
/**
* ForkJoin框架
*/
@Test
public void test() {
Instant start = Instant.now();
ForkJoinPool pool = new ForkJoinPool();
ForkJoinTask<Long> task = new ForkJoinCalculate(0L,1000000000000L);
Long sum = pool.invoke(task);
System.out.println(sum);
Instant end = Instant.now();
System.out.println(Duration.between(start, end).toMillis());//269948
}
/**
* 普通for循环
* for循环是比较底层的 效率比较高 如果数值过小拆分也需要时间,如果拆分时间大于单线程时间就不能拆分 本机测试一万亿才趋于临界值
*/
@Test
public void test1() {
Instant start = Instant.now();
long sum = 0 ;
for (long i = 1; i < 1000000000000L; i++) {
sum = sum + i;
}
Instant end = Instant.now();
System.out.println(sum);
System.out.println(Duration.between(start, end).toMillis());//260251
}
/**
* java8并行流
*/
@Test
public void test2() {
Instant start = Instant.now();
long sum = 0 ;
LongStream.rangeClosed(0, 1000000000000L).parallel().reduce(0,Long::sum);
Instant end = Instant.now();
System.out.println(sum);
System.out.println(Duration.between(start, end).toMillis());//134735
}
}