LockSupport导致线程阻塞, 运行main方法, 可重现, jdk:1.7
- 使用CountDownLatch即可避免该问题.代码已经贴在了下方的回答中. 但目前我更需要知道的是LockSupport为什么不行
代码块:
package com.duobaoyu.dby.enterprise.service.impl;
import lombok.extern.slf4j.Slf4j;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.LockSupport;
@Slf4j
public class Test {
public static void saveOrderData() {
// 定义开启的线程数
AtomicInteger totalThreadCount = new AtomicInteger(5);
// 定义没有执行结束的线程集合
List<Thread> unFinishedThread = Collections.synchronizedList(new ArrayList<>());
List<CompletableFuture<Void>> list = new ArrayList<>();
list.add(save(unFinishedThread, totalThreadCount));
list.add(save2(unFinishedThread, totalThreadCount));
list.add(save3(unFinishedThread, totalThreadCount));
list.add(save4(unFinishedThread, totalThreadCount));
list.add(save5(unFinishedThread, totalThreadCount));
CompletableFuture.allOf(list.toArray(new CompletableFuture[totalThreadCount.get()])).join();
}
private static CompletableFuture<Void> save(List<Thread> unFinishedThread, AtomicInteger totalThreadCount) {
return CompletableFuture.runAsync(() -> {
try {
Thread.sleep(1000L);
Thread thread = Thread.currentThread();
log.info("执行方法: orderSave, 线程名:{}", thread.getName());
threadBlocking(thread, unFinishedThread, totalThreadCount);
} catch (Exception ignored) {
}
});
}
private static CompletableFuture<Void> save2(List<Thread> unFinishedThread, AtomicInteger totalThreadCount) {
return CompletableFuture.runAsync(() -> {
try {
Thread.sleep(900L);
Thread thread = Thread.currentThread();
log.info("执行方法: approvalInfoSave, 线程名:{}", thread.getName());
threadBlocking(thread, unFinishedThread, totalThreadCount);
} catch (Exception ignored) {
}
});
}
private static CompletableFuture<Void> save3(List<Thread> unFinishedThread, AtomicInteger totalThreadCount) {
return CompletableFuture.runAsync(() -> {
try {
Thread.sleep(800L);
Thread thread = Thread.currentThread();
log.info("执行方法: orderAddressSave, 线程名:{}", thread.getName());
threadBlocking(thread, unFinishedThread, totalThreadCount);
} catch (Exception ignored) {
}
});
}
private static CompletableFuture<Void> save4(List<Thread> unFinishedThread, AtomicInteger totalThreadCount) {
return CompletableFuture.runAsync(() -> {
try {
Thread.sleep(700L);
Thread thread = Thread.currentThread();
log.info("执行方法: subOrderSave, 线程名:{}", thread.getName());
threadBlocking(thread, unFinishedThread, totalThreadCount);
} catch (Exception ignored) {
}
});
}
private static CompletableFuture<Void> save5(List<Thread> unFinishedThread, AtomicInteger totalThreadCount) {
return CompletableFuture.runAsync(() -> {
try {
Thread.sleep(600L);
Thread thread = Thread.currentThread();
log.info("执行方法: orderGoodsSave, 线程名:{}", thread.getName());
threadBlocking(thread, unFinishedThread, totalThreadCount);
} catch (Exception ignored) {
}
});
}
private static void threadBlocking(Thread thread, List<Thread> unFinishedThread, AtomicInteger totalThreadCount) {
// 添加到没有执行结束的线程集合
unFinishedThread.add(thread);
// 每个线程都在悬停前开启唤醒检查
notifyAllThread(unFinishedThread, totalThreadCount);
log.info("线程: {}, 开始悬停", thread.getName());
LockSupport.park();
log.info("线程: {}, 执行完毕", thread.getName());
}
private static void notifyAllThread(List<Thread> unFinishedThread, AtomicInteger totalThreadCount) {
if (unFinishedThread.size() == totalThreadCount.get()) {
for (Thread thread : unFinishedThread) {
LockSupport.unpark(thread);
log.info("线程: [{}]被唤醒", thread.getName());
}
}
}
public static void main(String[] args) {
for (int i = 0; i < 100; i++) {
System.out.println("开始任务!" + i);
saveOrderData();
System.out.println("结束任务!" + i);
}
}
}
从jdk的文档来看, 是不会造成阻塞的. 目前也没有发现固定的规律, 想知道造成这种问题的原因, 以及如何解决这个问题了