以下代码导致死锁。在示例代码中,我正在使用parallelStream(使用默认公共ForkJoin池)并行处理一个调用processString的String列表。然后,processString方法使用parallelStream并行调用processCharacter,但这一次是在自定义ThreadPool中进行的。
Backend Config :
BackendType : Instance groups
Instance groups : POints to the instance containing my instance.
PortNumbers : 443
Balancing Mode : Util
Maximum CPU util : 80%
Health check : Https health check on port-443, timeout 5s, interval 10s.
FrontEnd config :
Protocol : SSL
POrt-443.
Certificate : uploaded_certificate
SSL Policy : Only allow TLSv2.
Proxy Protocol : OFF
代码并非总是会陷入僵局,而是会陷入僵局。 5次运行一次。当代码以死锁运行时,将产生以下输出:
public class ForkJoinTest {
static final ExecutorService originalExecutor = Executors.newFixedThreadPool(2);
static final ExecutorService EXECUTOR = MoreExecutors.getExitingExecutorService(
(ThreadPoolExecutor) originalExecutor, 5, TimeUnit.SECONDS);
public static void main(String[] args) {
System.out
.println("Forkjoin pool size: " + (Runtime.getRuntime().availableProcessors() - 1));
final List<String> strings = listOfRandomString(10000);
strings.parallelStream().forEach(str -> processString(str));
}
private static void processString(final String string) {
try {
System.out.println("Processing string pause: " + string + ": " + Thread.currentThread()
.getName());
System.out.println("Processing string resume: " + string);
final List<Character> chars = new ArrayList<>();
for (Character ch : string.toCharArray()) {
chars.add(ch);
}
final Runnable updateTask = () -> {
chars.parallelStream().forEach(ch -> processCharacter(string,
ch));
};
Future future = EXECUTOR.submit(updateTask);
System.out.println("Wait of Future on Thread: " + Thread.currentThread().getName());
future.get();
} catch (Exception e) {
e.printStackTrace();
}
}
private static void processCharacter(final String str, final Character character) {
try {
System.out
.println("processing character: " + character + "Processing string pause: " + str + ": " + Thread
.currentThread()
.getName());
Thread.sleep(2);
} catch (Exception e) {
e.printStackTrace();
}
}
private static List<String> listOfRandomString(final int size) {
final List<String> list = new ArrayList<>(size);
for (int i = 0; i < size; i++) {
list.add(UUID.randomUUID().toString());
}
return list;
}
}
当代码不死锁时,输出如下:
Forkjoin pool size: 3
Processing string pause: 706fdcc5-235d-4513-aa73-ccc5ff3b7c96: ForkJoinPool.commonPool-worker-2
Processing string pause: 19814b98-8326-4531-b9f3-535c5a646076: ForkJoinPool.commonPool-worker-3
Processing string resume: 19814b98-8326-4531-b9f3-535c5a646076
Processing string pause: 2f2a3e3f-3def-4663-b024-0560f374e5fb: ForkJoinPool.commonPool-worker-1
Processing string resume: 2f2a3e3f-3def-4663-b024-0560f374e5fb
Processing string pause: 21c38331-7010-479b-bf8a-67e0557fee22: main
Processing string resume: 706fdcc5-235d-4513-aa73-ccc5ff3b7c96
Processing string resume: 21c38331-7010-479b-bf8a-67e0557fee22
Wait of Future on Thread: ForkJoinPool.commonPool-worker-2
Wait of Future on Thread: ForkJoinPool.commonPool-worker-3
Wait of Future on Thread: main
Wait of Future on Thread: ForkJoinPool.commonPool-worker-1
processing character: 3Processing string pause: 19814b98-8326-4531-b9f3-535c5a646076: pool-1-thread-1
processing character: 4Processing string pause: 2f2a3e3f-3def-4663-b024-0560f374e5fb: pool-1-thread-2
processing character: -Processing string pause: 19814b98-8326-4531-b9f3-535c5a646076: pool-1-thread-1
processing character: -Processing string pause: 2f2a3e3f-3def-4663-b024-0560f374e5fb: pool-1-thread-2
processing character: 5Processing string pause: 19814b98-8326-4531-b9f3-535c5a646076: pool-1-thread-1
processing character: eProcessing string pause: 2f2a3e3f-3def-4663-b024-0560f374e5fb: pool-1-thread-2
processing character: 3Processing string pause: 19814b98-8326-4531-b9f3-535c5a646076: pool-1-thread-1
processing character: fProcessing string pause: 2f2a3e3f-3def-4663-b024-0560f374e5fb: pool-1-thread-2
processing character: 5Processing string pause: 19814b98-8326-4531-b9f3-535c5a646076: pool-1-thread-1
processing character: 3Processing string pause: 2f2a3e3f-3def-4663-b024-0560f374e5fb: pool-1-thread-2
processing character: dProcessing string pause: 2f2a3e3f-3def-4663-b024-0560f374e5fb: pool-1-thread-2
processing character: 2Processing string pause: 19814b98-8326-4531-b9f3-535c5a646076: pool-1-thread-1
processing character: 6Processing string pause: 19814b98-8326-4531-b9f3-535c5a646076: pool-1-thread-1
processing character: 4Processing string pause: 2f2a3e3f-3def-4663-b024-0560f374e5fb: pool-1-thread-2
processing character: eProcessing string pause: 2f2a3e3f-3def-4663-b024-0560f374e5fb: pool-1-thread-2
processing character: 4Processing string pause: 19814b98-8326-4531-b9f3-535c5a646076: pool-1-thread-1
processing character: 0Processing string pause: 2f2a3e3f-3def-4663-b024-0560f374e5fb: pool-1-thread-2
processing character: 6Processing string pause: 19814b98-8326-4531-b9f3-535c5a646076: pool-1-thread-1
processing character: 2Processing string pause: 2f2a3e3f-3def-4663-b024-0560f374e5fb: pool-1-thread-2
processing character: 9Processing string pause: 19814b98-8326-4531-b9f3-535c5a646076: pool-1-thread-1
processing character: 0Processing string pause: 2f2a3e3f-3def-4663-b024-0560f374e5fb: pool-1-thread-2
processing character: fProcessing string pause: 19814b98-8326-4531-b9f3-535c5a646076: pool-1-thread-1
processing character: 5Processing string pause: 2f2a3e3f-3def-4663-b024-0560f374e5fb: pool-1-thread-2
processing character: -Processing string pause: 19814b98-8326-4531-b9f3-535c5a646076: pool-1-thread-1
processing character: bProcessing string pause: 19814b98-8326-4531-b9f3-535c5a646076: pool-1-thread-1
processing character: 6Processing string pause: 2f2a3e3f-3def-4663-b024-0560f374e5fb: pool-1-thread-2
processing character: -Processing string pause: 2f2a3e3f-3def-4663-b024-0560f374e5fb: pool-1-thread-2
processing character: bProcessing string pause: 2f2a3e3f-3def-4663-b024-0560f374e5fb: pool-1-thread-2
processing character: 3Processing string pause: 2f2a3e3f-3def-4663-b024-0560f374e5fb: pool-1-thread-2
processing character: eProcessing string pause: 2f2a3e3f-3def-4663-b024-0560f374e5fb: pool-1-thread-2
processing character: 3Processing string pause: 2f2a3e3f-3def-4663-b024-0560f374e5fb: pool-1-thread-2
processing character: fProcessing string pause: 2f2a3e3f-3def-4663-b024-0560f374e5fb: pool-1-thread-2
processing character: -Processing string pause: 2f2a3e3f-3def-4663-b024-0560f374e5fb: pool-1-thread-2
processing character: 2Processing string pause: 2f2a3e3f-3def-4663-b024-0560f374e5fb: pool-1-thread-2
processing character: aProcessing string pause: 2f2a3e3f-3def-4663-b024-0560f374e5fb: pool-1-thread-2
processing character: 2Processing string pause: 2f2a3e3f-3def-4663-b024-0560f374e5fb: pool-1-thread-2
processing character: fProcessing string pause: 2f2a3e3f-3def-4663-b024-0560f374e5fb: pool-1-thread-2
processing character: 6Processing string pause: 2f2a3e3f-3def-4663-b024-0560f374e5fb: pool-1-thread-2
processing character: 6Processing string pause: 2f2a3e3f-3def-4663-b024-0560f374e5fb: pool-1-thread-2
processing character: 3Processing string pause: 2f2a3e3f-3def-4663-b024-0560f374e5fb: pool-1-thread-2
processing character: -Processing string pause: 2f2a3e3f-3def-4663-b024-0560f374e5fb: pool-1-thread-2
processing character: 4Processing string pause: 2f2a3e3f-3def-4663-b024-0560f374e5fb: pool-1-thread-2
死锁运行的线程转储:
Forkjoin pool size: 3
Processing string pause: 8c8aeba8-fbf8-4d80-8fb7-bb97ccf05e68: ForkJoinPool.commonPool-worker-1
Processing string pause: a1311746-ba82-4541-9fbd-37d25857944d: ForkJoinPool.commonPool-worker-3
Processing string resume: a1311746-ba82-4541-9fbd-37d25857944d
Processing string pause: 4e5f6b79-bd48-4328-8d5c-252781bf9359: ForkJoinPool.commonPool-worker-2
Processing string resume: 4e5f6b79-bd48-4328-8d5c-252781bf9359
Processing string pause: 48ebca74-2fa9-486b-9467-8b40b3f2617f: main
Processing string resume: 8c8aeba8-fbf8-4d80-8fb7-bb97ccf05e68
Processing string resume: 48ebca74-2fa9-486b-9467-8b40b3f2617f
Wait of Future on Thread: ForkJoinPool.commonPool-worker-1
Wait of Future on Thread: ForkJoinPool.commonPool-worker-3
Wait of Future on Thread: ForkJoinPool.commonPool-worker-2
Wait of Future on Thread: main
processing character: cProcessing string pause: 4e5f6b79-bd48-4328-8d5c-252781bf9359: pool-1-thread-2
processing character: 7Processing string pause: 8c8aeba8-fbf8-4d80-8fb7-bb97ccf05e68: pool-1-thread-1
processing character: -Processing string pause: 8c8aeba8-fbf8-4d80-8fb7-bb97ccf05e68: pool-1-thread-1
processing character: -Processing string pause: 4e5f6b79-bd48-4328-8d5c-252781bf9359: pool-1-thread-2
processing character: 2Processing string pause: 4e5f6b79-bd48-4328-8d5c-252781bf9359: pool-1-thread-2
processing character: bProcessing string pause: 8c8aeba8-fbf8-4d80-8fb7-bb97ccf05e68: pool-1-thread-1
processing character: bProcessing string pause: 8c8aeba8-fbf8-4d80-8fb7-bb97ccf05e68: pool-1-thread-1
processing character: 5Processing string pause: 4e5f6b79-bd48-4328-8d5c-252781bf9359: pool-1-thread-2
processing character: 9Processing string pause: 8c8aeba8-fbf8-4d80-8fb7-bb97ccf05e68: pool-1-thread-1
processing character: 2Processing string pause: 4e5f6b79-bd48-4328-8d5c-252781bf9359: pool-1-thread-2
processing character: dProcessing string pause: 4e5f6b79-bd48-4328-8d5c-252781bf9359: pool-1-thread-2
processing character: fProcessing string pause: 8c8aeba8-fbf8-4d80-8fb7-bb97ccf05e68: pool-1-thread-1
processing character: 5Processing string pause: 4e5f6b79-bd48-4328-8d5c-252781bf9359: pool-1-thread-2
processing character: bProcessing string pause: 8c8aeba8-fbf8-4d80-8fb7-bb97ccf05e68: pool-1-thread-1
processing character: -Processing string pause: 8c8aeba8-fbf8-4d80-8fb7-bb97ccf05e68: pool-1-thread-1
processing character: -Processing string pause: 4e5f6b79-bd48-4328-8d5c-252781bf9359: pool-1-thread-2
processing character: 8Processing string pause: 8c8aeba8-fbf8-4d80-8fb7-bb97ccf05e68: pool-1-thread-1
processing character: 8Processing string pause: 4e5f6b79-bd48-4328-8d5c-252781bf9359: pool-1-thread-2
processing character: fProcessing string pause: 4e5f6b79-bd48-4328-8d5c-252781bf9359: pool-1-thread-2
processing character: 0Processing string pause: 8c8aeba8-fbf8-4d80-8fb7-bb97ccf05e68: pool-1-thread-1
processing character: 9Processing string pause: 4e5f6b79-bd48-4328-8d5c-252781bf9359: pool-1-thread-2
processing character: 5Processing string pause: 8c8aeba8-fbf8-4d80-8fb7-bb97ccf05e68: pool-1-thread-1
processing character: eProcessing string pause: 8c8aeba8-fbf8-4d80-8fb7-bb97ccf05e68: pool-1-thread-1
processing character: 3Processing string pause: 4e5f6b79-bd48-4328-8d5c-252781bf9359: pool-1-thread-2
processing character: 6Processing string pause: 8c8aeba8-fbf8-4d80-8fb7-bb97ccf05e68: pool-1-thread-1
processing character: 5Processing string pause: 4e5f6b79-bd48-4328-8d5c-252781bf9359: pool-1-thread-2
processing character: 8Processing string pause: 8c8aeba8-fbf8-4d80-8fb7-bb97ccf05e68: pool-1-thread-1
processing character: 9Processing string pause: 4e5f6b79-bd48-4328-8d5c-252781bf9359: pool-1-thread-2
processing character: 1Processing string pause: 4e5f6b79-bd48-4328-8d5c-252781bf9359: pool-1-thread-2
processing character: cProcessing string pause: 8c8aeba8-fbf8-4d80-8fb7-bb97ccf05e68: pool-1-thread-1
processing character: fProcessing string pause: 8c8aeba8-fbf8-4d80-8fb7-bb97ccf05e68: pool-1-thread-1
processing character: bProcessing string pause: 4e5f6b79-bd48-4328-8d5c-252781bf9359: pool-1-thread-2
processing character: 7Processing string pause: 4e5f6b79-bd48-4328-8d5c-252781bf9359: pool-1-thread-2
processing character: 7Processing string pause: 8c8aeba8-fbf8-4d80-8fb7-bb97ccf05e68: pool-1-thread-1
processing character: 8Processing string pause: 4e5f6b79-bd48-4328-8d5c-252781bf9359: pool-1-thread-2
processing character: cProcessing string pause: 8c8aeba8-fbf8-4d80-8fb7-bb97ccf05e68: pool-1-thread-1
processing character: 4Processing string pause: 4e5f6b79-bd48-4328-8d5c-252781bf9359: pool-1-thread-2
processing character: fProcessing string pause: 8c8aeba8-fbf8-4d80-8fb7-bb97ccf05e68: pool-1-thread-1
processing character: 8Processing string pause: 4e5f6b79-bd48-4328-8d5c-252781bf9359: pool-1-thread-2
processing character: 8Processing string pause: 8c8aeba8-fbf8-4d80-8fb7-bb97ccf05e68: pool-1-thread-1
processing character: bProcessing string pause: 4e5f6b79-bd48-4328-8d5c-252781bf9359: pool-1-thread-2
processing character: fProcessing string pause: 8c8aeba8-fbf8-4d80-8fb7-bb97ccf05e68: pool-1-thread-1
processing character: dProcessing string pause: 4e5f6b79-bd48-4328-8d5c-252781bf9359: pool-1-thread-2
processing character: bProcessing string pause: 8c8aeba8-fbf8-4d80-8fb7-bb97ccf05e68: pool-1-thread-1
processing character: 3Processing string pause: 4e5f6b79-bd48-4328-8d5c-252781bf9359: pool-1-thread-2
processing character: dProcessing string pause: 8c8aeba8-fbf8-4d80-8fb7-bb97ccf05e68: pool-1-thread-1
processing character: 2Processing string pause: 4e5f6b79-bd48-4328-8d5c-252781bf9359: pool-1-thread-2
processing character: 8Processing string pause: 8c8aeba8-fbf8-4d80-8fb7-bb97ccf05e68: pool-1-thread-1
processing character: 8Processing string pause: 4e5f6b79-bd48-4328-8d5c-252781bf9359: pool-1-thread-2
processing character: 0Processing string pause: 8c8aeba8-fbf8-4d80-8fb7-bb97ccf05e68: pool-1-thread-1
processing character: -Processing string pause: 4e5f6b79-bd48-4328-8d5c-252781bf9359: pool-1-thread-2
processing character: -Processing string pause: 8c8aeba8-fbf8-4d80-8fb7-bb97ccf05e68: pool-1-thread-1
processing character: 4Processing string pause: 4e5f6b79-bd48-4328-8d5c-252781bf9359: pool-1-thread-2
processing character: 4Processing string pause: 8c8aeba8-fbf8-4d80-8fb7-bb97ccf05e68: pool-1-thread-1
processing character: 6Processing string pause: 4e5f6b79-bd48-4328-8d5c-252781bf9359: pool-1-thread-2
processing character: eProcessing string pause: 8c8aeba8-fbf8-4d80-8fb7-bb97ccf05e68: pool-1-thread-1
processing character: bProcessing string pause: 4e5f6b79-bd48-4328-8d5c-252781bf9359: pool-1-thread-2
processing character: bProcessing string pause: 8c8aeba8-fbf8-4d80-8fb7-bb97ccf05e68: pool-1-thread-1
processing character: aProcessing string pause: 8c8aeba8-fbf8-4d80-8fb7-bb97ccf05e68: pool-1-thread-1
processing character: 7Processing string pause: 4e5f6b79-bd48-4328-8d5c-252781bf9359: pool-1-thread-2
processing character: 8Processing string pause: 8c8aeba8-fbf8-4d80-8fb7-bb97ccf05e68: pool-1-thread-1
processing character: 9Processing string pause: 4e5f6b79-bd48-4328-8d5c-252781bf9359: pool-1-thread-2
processing character: -Processing string pause: 4e5f6b79-bd48-4328-8d5c-252781bf9359: pool-1-thread-2
processing character: -Processing string pause: 8c8aeba8-fbf8-4d80-8fb7-bb97ccf05e68: pool-1-thread-1
processing character: 5Processing string pause: 4e5f6b79-bd48-4328-8d5c-252781bf9359: pool-1-thread-2
processing character: 8Processing string pause: 8c8aeba8-fbf8-4d80-8fb7-bb97ccf05e68: pool-1-thread-1
processing character: aProcessing string pause: 8c8aeba8-fbf8-4d80-8fb7-bb97ccf05e68: pool-1-thread-1
processing character: fProcessing string pause: 4e5f6b79-bd48-4328-8d5c-252781bf9359: pool-1-thread-2
processing character: 8Processing string pause: 8c8aeba8-fbf8-4d80-8fb7-bb97ccf05e68: pool-1-thread-1
processing character: 4Processing string pause: 4e5f6b79-bd48-4328-8d5c-252781bf9359: pool-1-thread-2
processing character: cProcessing string pause: 8c8aeba8-fbf8-4d80-8fb7-bb97ccf05e68: pool-1-thread-1
processing character: eProcessing string pause: 4e5f6b79-bd48-4328-8d5c-252781bf9359: pool-1-thread-2
Processing string pause: 58fa7ebd-6f4a-4ec0-8515-84148d870b0c: ForkJoinPool.commonPool-worker-1
Processing string resume: 58fa7ebd-6f4a-4ec0-8515-84148d870b0c
processing character: dProcessing string pause: a1311746-ba82-4541-9fbd-37d25857944d: pool-1-thread-1
Wait of Future on Thread: ForkJoinPool.commonPool-worker-1
Processing string pause: b941108a-c7a9-499e-b951-e94206ffa553: ForkJoinPool.commonPool-worker-2
Processing string resume: b941108a-c7a9-499e-b951-e94206ffa553
Wait of Future on Thread: ForkJoinPool.commonPool-worker-2
....
在parallelStream中,使用自定义线程,processCharacter在自定义ExecutorService的2个线程上执行(从输出日志中可以明显看出),因此我无法理解为什么它陷入僵局。 3个Common-ForkJoinPool线程被processString占用,但是CustomerPool的2个线程应该能够完成每个字符的处理。因此,不应阻止处理。似乎当parallelStream使用自定义ThreadPool时我会丢失一些东西,因为如果我使用ForkJoinPool而不是FixedThreadPool永远不会发生死锁。