FutureListTest
package com.xiaobu.juc;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.StopWatch;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;
/**
* The type Future list test.
*
* @author xiaobu
* @className FutureListTest.java
* @createTime 2022年06月30日 13:54:00
*/
@Slf4j
public class FutureListTest {
/**
* {@link FutureTask#get() 获取任务的执行结果}
*
* @param args the input arguments
*/
@SneakyThrows
public static void main(String[] args) {
StopWatch stopWatch = new StopWatch();
stopWatch.start("test");
List<String> list = new ArrayList<>();
list.add("1");
list.add("2");
list.add("3");
list.add("4");
list.add("5");
// ThreadPoolExecutor threadPoolExecutor = ParallelUtils.newFixedThreadPool(3);
// 不建议使用Executors创建
ExecutorService threadPoolExecutor = Executors.newFixedThreadPool(3);
Future<List<String>> future1 = threadPoolExecutor.submit(() ->
{
try {
TimeUnit.SECONDS.sleep(2);
} catch (InterruptedException e) {
e.printStackTrace();
}
},
list.subList(0, 2));
Future<List<String>> future2 = threadPoolExecutor.submit(() -> {
try {
TimeUnit.SECONDS.sleep(2);
} catch (InterruptedException e) {
e.printStackTrace();
}
}, list.subList(2, 4));
Future<List<String>> future3 = threadPoolExecutor.submit(() -> {
try {
TimeUnit.SECONDS.sleep(2);
} catch (InterruptedException e) {
e.printStackTrace();
}
}, list.subList(4, 5));
List<Future<List<String>>> futures = new ArrayList<>();
futures.add(future1);
futures.add(future2);
futures.add(future3);
for (Future<List<String>> future : futures) {
System.out.println("future.get() = " + future.get());
}
threadPoolExecutor.shutdown();
stopWatch.stop();
System.out.println("耗时 = " + stopWatch.getTotalTimeMillis());
}
}
/**
* Awaits completion or aborts on interrupt or timeout.
*
* @param timed true if use timed waits
* @param nanos time to wait, if timed
* @return state upon completion
*/
private int awaitDone(boolean timed, long nanos)
throws InterruptedException {
final long deadline = timed ? System.nanoTime() + nanos : 0L;
WaitNode q = null;
boolean queued = false;
for (;;) {
if (Thread.interrupted()) {
removeWaiter(q);
throw new InterruptedException();
}
//1. 读取状态
//1.1 如果s > COMPLETING,表示任务已经执行结束,或者发生异常结束了,就不会阻塞,直接返回
int s = state;
if (s > COMPLETING) {
if (q != null)
q.thread = null;
return s;
}
else if (s == COMPLETING) // cannot time out yet
/**
* 当前线程从执行状态(运行状态)变为可执行态(就绪状态)
* 就是说当一个线程使用了这个方法之后,它就会把自己CPU执行的时间让掉,让自己或者其它的线程运行。
*
* 打个比方:现在有很多人在排队上厕所,好不容易轮到这个人上厕所了,突然这个人说:“我要和大家来个竞赛,看谁先抢到厕所!”,然后所有的人在同一起跑线冲向厕所,有可能是别人抢到了,也有可能他自己有抢到了。我们还知道线程有个优先级的问题,那么手里有优先权的这些人就一定能抢到厕所的位置吗? 不一定的,他们只是概率上大些,也有可能没特权的抢到了。
*/
Thread.yield();
else if (q == null)
q = new WaitNode();
else if (!queued)
queued = UNSAFE.compareAndSwapObject(this, waitersOffset,
q.next = waiters, q);
else if (timed) {
nanos = deadline - System.nanoTime();
if (nanos <= 0L) {
removeWaiter(q);
return state;
}
LockSupport.parkNanos(this, nanos);
}
else
LockSupport.park(this);
}
}
InvokeAllTest
package com.xiaobu.juc;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.StopWatch;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.concurrent.*;
/**
* @author xiaobu
* @className InvokeAllTest.java
* @createTime 2022年06月30日 13:54:00
*/
@Slf4j
public class InvokeAllTest {
/**
* {@link AbstractExecutorService#invokeAll(Collection)} () }
*
* @param args the input arguments
*/
@SneakyThrows
public static void main(String[] args) {
StopWatch stopWatch = new StopWatch();
stopWatch.start("test");
List<String> list = new ArrayList<>();
list.add("1");
list.add("2");
list.add("3");
list.add("4");
list.add("5");
List<String> mList;
ExecutorService threadPoolExecutor = Executors.newFixedThreadPool(3);
// 不建议使用Executors创建
// ThreadPoolExecutor threadPoolExecutor = ParallelUtils.newFixedThreadPool(3);
Callable<List<String>> task1 = () -> {
try {
TimeUnit.SECONDS.sleep(2);
} catch (InterruptedException e) {
e.printStackTrace();
}
return list.subList(0, 2);
};
Callable<List<String>> task2 = () -> {
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
return list.subList(2, 4);
};
Callable<List<String>> task3 = () -> list.subList(4, 5);
List<Callable<List<String>>> taskList = new ArrayList<>();
taskList.add(task1);
taskList.add(task2);
taskList.add(task3);
List<Future<List<String>>> futures = threadPoolExecutor.invokeAll(taskList);
for (Future<List<String>> future : futures) {
mList = future.get();
mList.forEach(System.out::println);
}
threadPoolExecutor.shutdown();
stopWatch.stop();
System.out.println("耗时 = " + stopWatch.getTotalTimeMillis());
}
}
AllOfTest
package com.xiaobu.juc;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.StopWatch;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.*;
/**
* The type Future list test.
*
* @author xiaobu
* @className FutureListTest.java
* @createTime 2022年06月30日 13:54:00
*/
@Slf4j
public class AllOfTest {
/**
* {@link FutureTask#get() 获取任务的执行结果}
*
* @param args the input arguments
*/
@SneakyThrows
public static void main(String[] args) {
StopWatch stopWatch = new StopWatch();
stopWatch.start("test");
test();
stopWatch.stop();
System.out.println("耗时 = " + stopWatch.getTotalTimeMillis());
}
private static void test() throws InterruptedException, ExecutionException {
StopWatch stopWatch = new StopWatch();
stopWatch.start("submit");
List<String> list = new ArrayList<>();
list.add("1");
list.add("2");
list.add("3");
list.add("4");
list.add("5");
// 不建议使用Executors创建
ExecutorService threadPoolExecutor = Executors.newFixedThreadPool(3);
Map<String, Integer> resultMap = getThreadSizeAndThreadNum(list);
Integer threadSize = resultMap.get("threadSize");
Integer threadNum = resultMap.get("threadNum");
List<String> mList;
List<CompletableFuture<List<String>>> dataList = new ArrayList<>();
int j = 5;
for (int i = 0; i < threadNum; i++) {
if (i == threadNum - 1) {
mList = list.subList(i * threadSize, list.size());
} else {
mList = list.subList(i * threadSize, (i + 1) * threadSize);
}
List<String> finalList = mList;
int finalI = i;
CompletableFuture<List<String>> completableFuture = CompletableFuture.supplyAsync(() -> {
try {
int k = j - finalI;
// 模拟操作
TimeUnit.SECONDS.sleep(k);
} catch (InterruptedException e) {
e.printStackTrace();
}
return finalList;
}, threadPoolExecutor);
dataList.add(completableFuture);
}
CompletableFuture[] completableFutures = dataList.toArray(new CompletableFuture[0]);
// allOf里面有个andTree方法 等所有任务执行完成后按放入的顺序输出结果
CompletableFuture<Void> voidCompletableFuture = CompletableFuture.allOf(completableFutures);
List<String> result = new ArrayList<>();
// List<List<String>> lists = voidCompletableFuture.thenApply(v -> dataList.stream().map(completableFuture -> {
// try {
// return completableFuture.get();
// } catch (InterruptedException | ExecutionException e) {
// e.printStackTrace();
// }
// return null;
// }).collect(Collectors.toList())).get();
// log.info("【test】::lists ==> 【{}】", lists);
// Stream<List<String>> listStream = voidCompletableFuture.thenApply(v -> dataList.stream().map(completableFuture -> {
// try {
// return completableFuture.get();
// } catch (InterruptedException | ExecutionException e) {
// e.printStackTrace();
// }
// return null;
// })).get();
// 在这里阻塞
voidCompletableFuture.whenComplete((v, e) -> {
System.out.println("allOf complete");
}).get();
stopWatch.stop();
stopWatch.start("for");
for (CompletableFuture<List<String>> completableFuture : dataList) {
List<String> strings = completableFuture.get();
result.addAll(strings);
}
result.forEach(System.out::println);
stopWatch.stop();
System.out.println("stopWatch.prettyPrint() = " + stopWatch.prettyPrint());
threadPoolExecutor.shutdown();
}
public static Map<String, Integer> getThreadSizeAndThreadNum(List<String> subList) {
int threadSize = 1;
int threadNum = 0;
if (subList.size() <= 1) {
threadNum = subList.size();
}
if (subList.size() > 1) {
threadSize = 2;
threadNum = subList.size() % threadSize == 0 ? subList.size() / threadSize : subList.size() / threadSize + 1;
}
Map<String, Integer> map = new HashMap<>(4);
map.put("threadSize", threadSize);
map.put("threadNum", threadNum);
return map;
}
}
参考: