From f8232b1099aeadea1ac47f0cfe4bb7b826753483 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=B0=8F=E9=A9=AC=E5=93=A5?= Date: Sat, 13 Apr 2019 09:03:03 +0800 Subject: [PATCH] Add episode 23 --- .../concurrency/atomic/AtomicQuestion.java" | 26 ++++ .../barrier/CountDownLatchQuestion.java" | 37 ++++++ .../barrier/CyclicBarrierQuestion.java" | 45 +++++++ .../barrier/LegacyCountDownLatchDemo.java" | 123 ++++++++++++++++++ .../ArraysAsListMethodQuestion.java" | 20 +++ .../collection/BlockingQueueQuiz.java" | 22 ++++ .../ConcurrentHashSetQuestion.java" | 91 +++++++++++++ .../PriorityBlockingQueueQuiz.java" | 21 +++ .../collection/SynchronousQueueQuiz.java" | 18 +++ .../ThreadSafeCollectionQuestion.java" | 40 ++++++ .../future/CancellableFutureQuestion.java" | 47 +++++++ .../lock/ReentrantLockQuestion.java" | 78 +++++++++++ .../thread/AllThreadInfoQuestion.java" | 23 ++++ .../thread/AllThreadStackQuestion.java" | 20 +++ .../thread/CompleteAllThreadsQuestion.java" | 38 ++++++ .../thread/DaemonThreadQuestion.java" | 21 +++ .../thread/HowToStopThreadQuestion.java" | 53 ++++++++ .../thread/ProcessCreationQuestion.java" | 14 ++ .../thread/ShutdownHookQuestion.java" | 16 +++ .../thread/SynchronizedKeywordQuestion.java" | 16 +++ .../thread/ThreadCreationQuestion.java" | 26 ++++ .../thread/ThreadExceptionQuestion.java" | 27 ++++ .../thread/ThreadExecutionQuestion.java" | 118 +++++++++++++++++ .../ThreadPoolExecutorExceptionQuestion.java" | 44 +++++++ .../thread/ThreadStateQuestion.java" | 21 +++ .../thread/pool/ExecutorServiceQuestion.java" | 23 ++++ .../ThreadPoolExecutorThreadQuestion.java" | 81 ++++++++++++ 27 files changed, 1109 insertions(+) create mode 100644 "2019.04.12 \343\200\214\345\260\217\351\251\254\345\223\245\346\212\200\346\234\257\345\221\250\346\212\245\343\200\215- \347\254\254\344\272\214\345\215\201\344\270\211\346\234\237\343\200\212\351\235\242\350\257\225\350\231\220\346\210\221\345\215\203\347\231\276\351\201\215\357\274\214Java \345\271\266\345\217\221\347\234\237\350\256\250\345\216\214\357\274\210\347\273\255\357\274\211\343\200\213/java-concurrency/src/com/imooc/interview/questions/java/concurrency/atomic/AtomicQuestion.java" create mode 100644 "2019.04.12 \343\200\214\345\260\217\351\251\254\345\223\245\346\212\200\346\234\257\345\221\250\346\212\245\343\200\215- \347\254\254\344\272\214\345\215\201\344\270\211\346\234\237\343\200\212\351\235\242\350\257\225\350\231\220\346\210\221\345\215\203\347\231\276\351\201\215\357\274\214Java \345\271\266\345\217\221\347\234\237\350\256\250\345\216\214\357\274\210\347\273\255\357\274\211\343\200\213/java-concurrency/src/com/imooc/interview/questions/java/concurrency/barrier/CountDownLatchQuestion.java" create mode 100644 "2019.04.12 \343\200\214\345\260\217\351\251\254\345\223\245\346\212\200\346\234\257\345\221\250\346\212\245\343\200\215- \347\254\254\344\272\214\345\215\201\344\270\211\346\234\237\343\200\212\351\235\242\350\257\225\350\231\220\346\210\221\345\215\203\347\231\276\351\201\215\357\274\214Java \345\271\266\345\217\221\347\234\237\350\256\250\345\216\214\357\274\210\347\273\255\357\274\211\343\200\213/java-concurrency/src/com/imooc/interview/questions/java/concurrency/barrier/CyclicBarrierQuestion.java" create mode 100644 "2019.04.12 \343\200\214\345\260\217\351\251\254\345\223\245\346\212\200\346\234\257\345\221\250\346\212\245\343\200\215- \347\254\254\344\272\214\345\215\201\344\270\211\346\234\237\343\200\212\351\235\242\350\257\225\350\231\220\346\210\221\345\215\203\347\231\276\351\201\215\357\274\214Java \345\271\266\345\217\221\347\234\237\350\256\250\345\216\214\357\274\210\347\273\255\357\274\211\343\200\213/java-concurrency/src/com/imooc/interview/questions/java/concurrency/barrier/LegacyCountDownLatchDemo.java" create mode 100644 "2019.04.12 \343\200\214\345\260\217\351\251\254\345\223\245\346\212\200\346\234\257\345\221\250\346\212\245\343\200\215- \347\254\254\344\272\214\345\215\201\344\270\211\346\234\237\343\200\212\351\235\242\350\257\225\350\231\220\346\210\221\345\215\203\347\231\276\351\201\215\357\274\214Java \345\271\266\345\217\221\347\234\237\350\256\250\345\216\214\357\274\210\347\273\255\357\274\211\343\200\213/java-concurrency/src/com/imooc/interview/questions/java/concurrency/collection/ArraysAsListMethodQuestion.java" create mode 100644 "2019.04.12 \343\200\214\345\260\217\351\251\254\345\223\245\346\212\200\346\234\257\345\221\250\346\212\245\343\200\215- \347\254\254\344\272\214\345\215\201\344\270\211\346\234\237\343\200\212\351\235\242\350\257\225\350\231\220\346\210\221\345\215\203\347\231\276\351\201\215\357\274\214Java \345\271\266\345\217\221\347\234\237\350\256\250\345\216\214\357\274\210\347\273\255\357\274\211\343\200\213/java-concurrency/src/com/imooc/interview/questions/java/concurrency/collection/BlockingQueueQuiz.java" create mode 100644 "2019.04.12 \343\200\214\345\260\217\351\251\254\345\223\245\346\212\200\346\234\257\345\221\250\346\212\245\343\200\215- \347\254\254\344\272\214\345\215\201\344\270\211\346\234\237\343\200\212\351\235\242\350\257\225\350\231\220\346\210\221\345\215\203\347\231\276\351\201\215\357\274\214Java \345\271\266\345\217\221\347\234\237\350\256\250\345\216\214\357\274\210\347\273\255\357\274\211\343\200\213/java-concurrency/src/com/imooc/interview/questions/java/concurrency/collection/ConcurrentHashSetQuestion.java" create mode 100644 "2019.04.12 \343\200\214\345\260\217\351\251\254\345\223\245\346\212\200\346\234\257\345\221\250\346\212\245\343\200\215- \347\254\254\344\272\214\345\215\201\344\270\211\346\234\237\343\200\212\351\235\242\350\257\225\350\231\220\346\210\221\345\215\203\347\231\276\351\201\215\357\274\214Java \345\271\266\345\217\221\347\234\237\350\256\250\345\216\214\357\274\210\347\273\255\357\274\211\343\200\213/java-concurrency/src/com/imooc/interview/questions/java/concurrency/collection/PriorityBlockingQueueQuiz.java" create mode 100644 "2019.04.12 \343\200\214\345\260\217\351\251\254\345\223\245\346\212\200\346\234\257\345\221\250\346\212\245\343\200\215- \347\254\254\344\272\214\345\215\201\344\270\211\346\234\237\343\200\212\351\235\242\350\257\225\350\231\220\346\210\221\345\215\203\347\231\276\351\201\215\357\274\214Java \345\271\266\345\217\221\347\234\237\350\256\250\345\216\214\357\274\210\347\273\255\357\274\211\343\200\213/java-concurrency/src/com/imooc/interview/questions/java/concurrency/collection/SynchronousQueueQuiz.java" create mode 100644 "2019.04.12 \343\200\214\345\260\217\351\251\254\345\223\245\346\212\200\346\234\257\345\221\250\346\212\245\343\200\215- \347\254\254\344\272\214\345\215\201\344\270\211\346\234\237\343\200\212\351\235\242\350\257\225\350\231\220\346\210\221\345\215\203\347\231\276\351\201\215\357\274\214Java \345\271\266\345\217\221\347\234\237\350\256\250\345\216\214\357\274\210\347\273\255\357\274\211\343\200\213/java-concurrency/src/com/imooc/interview/questions/java/concurrency/collection/ThreadSafeCollectionQuestion.java" create mode 100644 "2019.04.12 \343\200\214\345\260\217\351\251\254\345\223\245\346\212\200\346\234\257\345\221\250\346\212\245\343\200\215- \347\254\254\344\272\214\345\215\201\344\270\211\346\234\237\343\200\212\351\235\242\350\257\225\350\231\220\346\210\221\345\215\203\347\231\276\351\201\215\357\274\214Java \345\271\266\345\217\221\347\234\237\350\256\250\345\216\214\357\274\210\347\273\255\357\274\211\343\200\213/java-concurrency/src/com/imooc/interview/questions/java/concurrency/future/CancellableFutureQuestion.java" create mode 100644 "2019.04.12 \343\200\214\345\260\217\351\251\254\345\223\245\346\212\200\346\234\257\345\221\250\346\212\245\343\200\215- \347\254\254\344\272\214\345\215\201\344\270\211\346\234\237\343\200\212\351\235\242\350\257\225\350\231\220\346\210\221\345\215\203\347\231\276\351\201\215\357\274\214Java \345\271\266\345\217\221\347\234\237\350\256\250\345\216\214\357\274\210\347\273\255\357\274\211\343\200\213/java-concurrency/src/com/imooc/interview/questions/java/concurrency/lock/ReentrantLockQuestion.java" create mode 100644 "2019.04.12 \343\200\214\345\260\217\351\251\254\345\223\245\346\212\200\346\234\257\345\221\250\346\212\245\343\200\215- \347\254\254\344\272\214\345\215\201\344\270\211\346\234\237\343\200\212\351\235\242\350\257\225\350\231\220\346\210\221\345\215\203\347\231\276\351\201\215\357\274\214Java \345\271\266\345\217\221\347\234\237\350\256\250\345\216\214\357\274\210\347\273\255\357\274\211\343\200\213/java-concurrency/src/com/imooc/interview/questions/java/concurrency/thread/AllThreadInfoQuestion.java" create mode 100644 "2019.04.12 \343\200\214\345\260\217\351\251\254\345\223\245\346\212\200\346\234\257\345\221\250\346\212\245\343\200\215- \347\254\254\344\272\214\345\215\201\344\270\211\346\234\237\343\200\212\351\235\242\350\257\225\350\231\220\346\210\221\345\215\203\347\231\276\351\201\215\357\274\214Java \345\271\266\345\217\221\347\234\237\350\256\250\345\216\214\357\274\210\347\273\255\357\274\211\343\200\213/java-concurrency/src/com/imooc/interview/questions/java/concurrency/thread/AllThreadStackQuestion.java" create mode 100644 "2019.04.12 \343\200\214\345\260\217\351\251\254\345\223\245\346\212\200\346\234\257\345\221\250\346\212\245\343\200\215- \347\254\254\344\272\214\345\215\201\344\270\211\346\234\237\343\200\212\351\235\242\350\257\225\350\231\220\346\210\221\345\215\203\347\231\276\351\201\215\357\274\214Java \345\271\266\345\217\221\347\234\237\350\256\250\345\216\214\357\274\210\347\273\255\357\274\211\343\200\213/java-concurrency/src/com/imooc/interview/questions/java/concurrency/thread/CompleteAllThreadsQuestion.java" create mode 100644 "2019.04.12 \343\200\214\345\260\217\351\251\254\345\223\245\346\212\200\346\234\257\345\221\250\346\212\245\343\200\215- \347\254\254\344\272\214\345\215\201\344\270\211\346\234\237\343\200\212\351\235\242\350\257\225\350\231\220\346\210\221\345\215\203\347\231\276\351\201\215\357\274\214Java \345\271\266\345\217\221\347\234\237\350\256\250\345\216\214\357\274\210\347\273\255\357\274\211\343\200\213/java-concurrency/src/com/imooc/interview/questions/java/concurrency/thread/DaemonThreadQuestion.java" create mode 100644 "2019.04.12 \343\200\214\345\260\217\351\251\254\345\223\245\346\212\200\346\234\257\345\221\250\346\212\245\343\200\215- \347\254\254\344\272\214\345\215\201\344\270\211\346\234\237\343\200\212\351\235\242\350\257\225\350\231\220\346\210\221\345\215\203\347\231\276\351\201\215\357\274\214Java \345\271\266\345\217\221\347\234\237\350\256\250\345\216\214\357\274\210\347\273\255\357\274\211\343\200\213/java-concurrency/src/com/imooc/interview/questions/java/concurrency/thread/HowToStopThreadQuestion.java" create mode 100644 "2019.04.12 \343\200\214\345\260\217\351\251\254\345\223\245\346\212\200\346\234\257\345\221\250\346\212\245\343\200\215- \347\254\254\344\272\214\345\215\201\344\270\211\346\234\237\343\200\212\351\235\242\350\257\225\350\231\220\346\210\221\345\215\203\347\231\276\351\201\215\357\274\214Java \345\271\266\345\217\221\347\234\237\350\256\250\345\216\214\357\274\210\347\273\255\357\274\211\343\200\213/java-concurrency/src/com/imooc/interview/questions/java/concurrency/thread/ProcessCreationQuestion.java" create mode 100644 "2019.04.12 \343\200\214\345\260\217\351\251\254\345\223\245\346\212\200\346\234\257\345\221\250\346\212\245\343\200\215- \347\254\254\344\272\214\345\215\201\344\270\211\346\234\237\343\200\212\351\235\242\350\257\225\350\231\220\346\210\221\345\215\203\347\231\276\351\201\215\357\274\214Java \345\271\266\345\217\221\347\234\237\350\256\250\345\216\214\357\274\210\347\273\255\357\274\211\343\200\213/java-concurrency/src/com/imooc/interview/questions/java/concurrency/thread/ShutdownHookQuestion.java" create mode 100644 "2019.04.12 \343\200\214\345\260\217\351\251\254\345\223\245\346\212\200\346\234\257\345\221\250\346\212\245\343\200\215- \347\254\254\344\272\214\345\215\201\344\270\211\346\234\237\343\200\212\351\235\242\350\257\225\350\231\220\346\210\221\345\215\203\347\231\276\351\201\215\357\274\214Java \345\271\266\345\217\221\347\234\237\350\256\250\345\216\214\357\274\210\347\273\255\357\274\211\343\200\213/java-concurrency/src/com/imooc/interview/questions/java/concurrency/thread/SynchronizedKeywordQuestion.java" create mode 100644 "2019.04.12 \343\200\214\345\260\217\351\251\254\345\223\245\346\212\200\346\234\257\345\221\250\346\212\245\343\200\215- \347\254\254\344\272\214\345\215\201\344\270\211\346\234\237\343\200\212\351\235\242\350\257\225\350\231\220\346\210\221\345\215\203\347\231\276\351\201\215\357\274\214Java \345\271\266\345\217\221\347\234\237\350\256\250\345\216\214\357\274\210\347\273\255\357\274\211\343\200\213/java-concurrency/src/com/imooc/interview/questions/java/concurrency/thread/ThreadCreationQuestion.java" create mode 100644 "2019.04.12 \343\200\214\345\260\217\351\251\254\345\223\245\346\212\200\346\234\257\345\221\250\346\212\245\343\200\215- \347\254\254\344\272\214\345\215\201\344\270\211\346\234\237\343\200\212\351\235\242\350\257\225\350\231\220\346\210\221\345\215\203\347\231\276\351\201\215\357\274\214Java \345\271\266\345\217\221\347\234\237\350\256\250\345\216\214\357\274\210\347\273\255\357\274\211\343\200\213/java-concurrency/src/com/imooc/interview/questions/java/concurrency/thread/ThreadExceptionQuestion.java" create mode 100644 "2019.04.12 \343\200\214\345\260\217\351\251\254\345\223\245\346\212\200\346\234\257\345\221\250\346\212\245\343\200\215- \347\254\254\344\272\214\345\215\201\344\270\211\346\234\237\343\200\212\351\235\242\350\257\225\350\231\220\346\210\221\345\215\203\347\231\276\351\201\215\357\274\214Java \345\271\266\345\217\221\347\234\237\350\256\250\345\216\214\357\274\210\347\273\255\357\274\211\343\200\213/java-concurrency/src/com/imooc/interview/questions/java/concurrency/thread/ThreadExecutionQuestion.java" create mode 100644 "2019.04.12 \343\200\214\345\260\217\351\251\254\345\223\245\346\212\200\346\234\257\345\221\250\346\212\245\343\200\215- \347\254\254\344\272\214\345\215\201\344\270\211\346\234\237\343\200\212\351\235\242\350\257\225\350\231\220\346\210\221\345\215\203\347\231\276\351\201\215\357\274\214Java \345\271\266\345\217\221\347\234\237\350\256\250\345\216\214\357\274\210\347\273\255\357\274\211\343\200\213/java-concurrency/src/com/imooc/interview/questions/java/concurrency/thread/ThreadPoolExecutorExceptionQuestion.java" create mode 100644 "2019.04.12 \343\200\214\345\260\217\351\251\254\345\223\245\346\212\200\346\234\257\345\221\250\346\212\245\343\200\215- \347\254\254\344\272\214\345\215\201\344\270\211\346\234\237\343\200\212\351\235\242\350\257\225\350\231\220\346\210\221\345\215\203\347\231\276\351\201\215\357\274\214Java \345\271\266\345\217\221\347\234\237\350\256\250\345\216\214\357\274\210\347\273\255\357\274\211\343\200\213/java-concurrency/src/com/imooc/interview/questions/java/concurrency/thread/ThreadStateQuestion.java" create mode 100644 "2019.04.12 \343\200\214\345\260\217\351\251\254\345\223\245\346\212\200\346\234\257\345\221\250\346\212\245\343\200\215- \347\254\254\344\272\214\345\215\201\344\270\211\346\234\237\343\200\212\351\235\242\350\257\225\350\231\220\346\210\221\345\215\203\347\231\276\351\201\215\357\274\214Java \345\271\266\345\217\221\347\234\237\350\256\250\345\216\214\357\274\210\347\273\255\357\274\211\343\200\213/java-concurrency/src/com/imooc/interview/questions/java/concurrency/thread/pool/ExecutorServiceQuestion.java" create mode 100644 "2019.04.12 \343\200\214\345\260\217\351\251\254\345\223\245\346\212\200\346\234\257\345\221\250\346\212\245\343\200\215- \347\254\254\344\272\214\345\215\201\344\270\211\346\234\237\343\200\212\351\235\242\350\257\225\350\231\220\346\210\221\345\215\203\347\231\276\351\201\215\357\274\214Java \345\271\266\345\217\221\347\234\237\350\256\250\345\216\214\357\274\210\347\273\255\357\274\211\343\200\213/java-concurrency/src/com/imooc/interview/questions/java/concurrency/thread/pool/ThreadPoolExecutorThreadQuestion.java" diff --git "a/2019.04.12 \343\200\214\345\260\217\351\251\254\345\223\245\346\212\200\346\234\257\345\221\250\346\212\245\343\200\215- \347\254\254\344\272\214\345\215\201\344\270\211\346\234\237\343\200\212\351\235\242\350\257\225\350\231\220\346\210\221\345\215\203\347\231\276\351\201\215\357\274\214Java \345\271\266\345\217\221\347\234\237\350\256\250\345\216\214\357\274\210\347\273\255\357\274\211\343\200\213/java-concurrency/src/com/imooc/interview/questions/java/concurrency/atomic/AtomicQuestion.java" "b/2019.04.12 \343\200\214\345\260\217\351\251\254\345\223\245\346\212\200\346\234\257\345\221\250\346\212\245\343\200\215- \347\254\254\344\272\214\345\215\201\344\270\211\346\234\237\343\200\212\351\235\242\350\257\225\350\231\220\346\210\221\345\215\203\347\231\276\351\201\215\357\274\214Java \345\271\266\345\217\221\347\234\237\350\256\250\345\216\214\357\274\210\347\273\255\357\274\211\343\200\213/java-concurrency/src/com/imooc/interview/questions/java/concurrency/atomic/AtomicQuestion.java" new file mode 100644 index 0000000..96b437b --- /dev/null +++ "b/2019.04.12 \343\200\214\345\260\217\351\251\254\345\223\245\346\212\200\346\234\257\345\221\250\346\212\245\343\200\215- \347\254\254\344\272\214\345\215\201\344\270\211\346\234\237\343\200\212\351\235\242\350\257\225\350\231\220\346\210\221\345\215\203\347\231\276\351\201\215\357\274\214Java \345\271\266\345\217\221\347\234\237\350\256\250\345\216\214\357\274\210\347\273\255\357\274\211\343\200\213/java-concurrency/src/com/imooc/interview/questions/java/concurrency/atomic/AtomicQuestion.java" @@ -0,0 +1,26 @@ +package com.imooc.interview.questions.java.concurrency.atomic; + +import java.util.concurrent.atomic.AtomicInteger; + +public class AtomicQuestion { + + private static int actualValue = 3; + + public static void main(String[] args) { + AtomicInteger atomicInteger = new AtomicInteger(3); + // if( value == 3 ) + // value = 5 + atomicInteger.compareAndSet(3, 5); + // 偏向锁 < CAS 操作 < 重锁(完全互斥) + // CAS 操作也是相对重的操作,它也是实现 synchronized 瘦锁(thin lock)的关键 + // https://wiki.openjdk.java.net/display/HotSpot/Synchronization + // 偏向锁就是避免 CAS(Compare And Set/Swap)操作 + // 汇编指令:cpmxchg + } + + private synchronized static void compareAndSet(int expectedValue, int newValue) { + if (actualValue == expectedValue) { + actualValue = newValue; + } + } +} diff --git "a/2019.04.12 \343\200\214\345\260\217\351\251\254\345\223\245\346\212\200\346\234\257\345\221\250\346\212\245\343\200\215- \347\254\254\344\272\214\345\215\201\344\270\211\346\234\237\343\200\212\351\235\242\350\257\225\350\231\220\346\210\221\345\215\203\347\231\276\351\201\215\357\274\214Java \345\271\266\345\217\221\347\234\237\350\256\250\345\216\214\357\274\210\347\273\255\357\274\211\343\200\213/java-concurrency/src/com/imooc/interview/questions/java/concurrency/barrier/CountDownLatchQuestion.java" "b/2019.04.12 \343\200\214\345\260\217\351\251\254\345\223\245\346\212\200\346\234\257\345\221\250\346\212\245\343\200\215- \347\254\254\344\272\214\345\215\201\344\270\211\346\234\237\343\200\212\351\235\242\350\257\225\350\231\220\346\210\221\345\215\203\347\231\276\351\201\215\357\274\214Java \345\271\266\345\217\221\347\234\237\350\256\250\345\216\214\357\274\210\347\273\255\357\274\211\343\200\213/java-concurrency/src/com/imooc/interview/questions/java/concurrency/barrier/CountDownLatchQuestion.java" new file mode 100644 index 0000000..3c52a5a --- /dev/null +++ "b/2019.04.12 \343\200\214\345\260\217\351\251\254\345\223\245\346\212\200\346\234\257\345\221\250\346\212\245\343\200\215- \347\254\254\344\272\214\345\215\201\344\270\211\346\234\237\343\200\212\351\235\242\350\257\225\350\231\220\346\210\221\345\215\203\347\231\276\351\201\215\357\274\214Java \345\271\266\345\217\221\347\234\237\350\256\250\345\216\214\357\274\210\347\273\255\357\274\211\343\200\213/java-concurrency/src/com/imooc/interview/questions/java/concurrency/barrier/CountDownLatchQuestion.java" @@ -0,0 +1,37 @@ +package com.imooc.interview.questions.java.concurrency.barrier; + +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + +public class CountDownLatchQuestion { + + public static void main(String[] args) throws InterruptedException { + + // 倒数计数 5 + CountDownLatch latch = new CountDownLatch(5); + + ExecutorService executorService = Executors.newFixedThreadPool(5); + + for (int i = 0; i < 4; i++) { + executorService.submit(() -> { + action(); + latch.countDown(); // -1 + }); + } + + // 等待完成 + // 当计数 > 0,会被阻塞 + latch.await(); + + System.out.println("Done"); + + // 关闭线程池 + executorService.shutdown(); + } + + private static void action() { + System.out.printf("线程[%s] 正在执行...\n", Thread.currentThread().getName()); // 2 + } + +} diff --git "a/2019.04.12 \343\200\214\345\260\217\351\251\254\345\223\245\346\212\200\346\234\257\345\221\250\346\212\245\343\200\215- \347\254\254\344\272\214\345\215\201\344\270\211\346\234\237\343\200\212\351\235\242\350\257\225\350\231\220\346\210\221\345\215\203\347\231\276\351\201\215\357\274\214Java \345\271\266\345\217\221\347\234\237\350\256\250\345\216\214\357\274\210\347\273\255\357\274\211\343\200\213/java-concurrency/src/com/imooc/interview/questions/java/concurrency/barrier/CyclicBarrierQuestion.java" "b/2019.04.12 \343\200\214\345\260\217\351\251\254\345\223\245\346\212\200\346\234\257\345\221\250\346\212\245\343\200\215- \347\254\254\344\272\214\345\215\201\344\270\211\346\234\237\343\200\212\351\235\242\350\257\225\350\231\220\346\210\221\345\215\203\347\231\276\351\201\215\357\274\214Java \345\271\266\345\217\221\347\234\237\350\256\250\345\216\214\357\274\210\347\273\255\357\274\211\343\200\213/java-concurrency/src/com/imooc/interview/questions/java/concurrency/barrier/CyclicBarrierQuestion.java" new file mode 100644 index 0000000..65bdb78 --- /dev/null +++ "b/2019.04.12 \343\200\214\345\260\217\351\251\254\345\223\245\346\212\200\346\234\257\345\221\250\346\212\245\343\200\215- \347\254\254\344\272\214\345\215\201\344\270\211\346\234\237\343\200\212\351\235\242\350\257\225\350\231\220\346\210\221\345\215\203\347\231\276\351\201\215\357\274\214Java \345\271\266\345\217\221\347\234\237\350\256\250\345\216\214\357\274\210\347\273\255\357\274\211\343\200\213/java-concurrency/src/com/imooc/interview/questions/java/concurrency/barrier/CyclicBarrierQuestion.java" @@ -0,0 +1,45 @@ +package com.imooc.interview.questions.java.concurrency.barrier; + +import java.util.concurrent.*; + +public class CyclicBarrierQuestion { + + public static void main(String[] args) throws InterruptedException { + + CyclicBarrier barrier = new CyclicBarrier(5); // 5 + + ExecutorService executorService = Executors.newFixedThreadPool(5); // 3 + + for (int i = 0; i < 20; i++) { + executorService.submit(() -> { + action(); + try { + // CyclicBarrier.await() = CountDownLatch.countDown() + await() + // 先计数 -1,再判断当计数 > 0 时候,才阻塞 + barrier.await(); + } catch (InterruptedException e) { + e.printStackTrace(); + } catch (BrokenBarrierException e) { + e.printStackTrace(); + } + }); + } + + // 尽可能不要执行完成再 reset + // 先等待 3 ms + executorService.awaitTermination(3, TimeUnit.MILLISECONDS); + // 再执行 CyclicBarrier reset + // reset 方法是一个废操作 + barrier.reset(); + + System.out.println("Done"); + + // 关闭线程池 + executorService.shutdown(); + } + + private static void action() { + System.out.printf("线程[%s] 正在执行...\n", Thread.currentThread().getName()); // 2 + } + +} diff --git "a/2019.04.12 \343\200\214\345\260\217\351\251\254\345\223\245\346\212\200\346\234\257\345\221\250\346\212\245\343\200\215- \347\254\254\344\272\214\345\215\201\344\270\211\346\234\237\343\200\212\351\235\242\350\257\225\350\231\220\346\210\221\345\215\203\347\231\276\351\201\215\357\274\214Java \345\271\266\345\217\221\347\234\237\350\256\250\345\216\214\357\274\210\347\273\255\357\274\211\343\200\213/java-concurrency/src/com/imooc/interview/questions/java/concurrency/barrier/LegacyCountDownLatchDemo.java" "b/2019.04.12 \343\200\214\345\260\217\351\251\254\345\223\245\346\212\200\346\234\257\345\221\250\346\212\245\343\200\215- \347\254\254\344\272\214\345\215\201\344\270\211\346\234\237\343\200\212\351\235\242\350\257\225\350\231\220\346\210\221\345\215\203\347\231\276\351\201\215\357\274\214Java \345\271\266\345\217\221\347\234\237\350\256\250\345\216\214\357\274\210\347\273\255\357\274\211\343\200\213/java-concurrency/src/com/imooc/interview/questions/java/concurrency/barrier/LegacyCountDownLatchDemo.java" new file mode 100644 index 0000000..1bc46d7 --- /dev/null +++ "b/2019.04.12 \343\200\214\345\260\217\351\251\254\345\223\245\346\212\200\346\234\257\345\221\250\346\212\245\343\200\215- \347\254\254\344\272\214\345\215\201\344\270\211\346\234\237\343\200\212\351\235\242\350\257\225\350\231\220\346\210\221\345\215\203\347\231\276\351\201\215\357\274\214Java \345\271\266\345\217\221\347\234\237\350\256\250\345\216\214\357\274\210\347\273\255\357\274\211\343\200\213/java-concurrency/src/com/imooc/interview/questions/java/concurrency/barrier/LegacyCountDownLatchDemo.java" @@ -0,0 +1,123 @@ +package com.imooc.interview.questions.java.concurrency.barrier; + +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.locks.Condition; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; + +public class LegacyCountDownLatchDemo { + + public static void main(String[] args) throws InterruptedException { + + // 倒数计数 5 + MyCountDownLatch latch = new MyCountDownLatch(5); + + ExecutorService executorService = Executors.newFixedThreadPool(5); + + for (int i = 0; i < 5; i++) { + executorService.submit(() -> { + action(); + latch.countDown(); // -1 + }); + } + + // 等待完成 + // 当计数 > 0,会被阻塞 + latch.await(); + + System.out.println("Done"); + + // 关闭线程池 + executorService.shutdown(); + } + + private static void action() { + System.out.printf("线程[%s] 正在执行...\n", Thread.currentThread().getName()); // 2 + } + + /** + * Java 1.5+ Lock 实现 + */ + private static class MyCountDownLatch { + + private int count; + + private final Lock lock = new ReentrantLock(); + + private final Condition condition = lock.newCondition(); + + private MyCountDownLatch(int count) { + this.count = count; + } + + public void await() throws InterruptedException { + // 当 count > 0 等待 + if (Thread.interrupted()) { + throw new InterruptedException(); + } + + lock.lock(); + try { + while (count > 0) { + condition.await(); // 阻塞当前线程 + } + } finally { + lock.unlock(); + } + } + + public void countDown() { + + lock.lock(); + try { + if (count < 1) { + return; + } + count--; + if (count < 1) { // 当数量减少至0时,唤起被阻塞的线程 + condition.signalAll(); + } + } finally { + lock.unlock(); + } + } + } + + /** + * Java < 1.5 实现 + */ + private static class LegacyCountDownLatch { + + private int count; + + private LegacyCountDownLatch(int count) { + this.count = count; + } + + public void await() throws InterruptedException { + // 当 count > 0 等待 + if (Thread.interrupted()) { + throw new InterruptedException(); + } + + synchronized (this) { + while (count > 0) { + wait(); // 阻塞当前线程 + } + } + } + + public void countDown() { + synchronized (this) { + if (count < 1) { + return; + } + count--; + if (count < 1) { // 当数量减少至0时,唤起被阻塞的线程 + notifyAll(); + } + } + } + } +} diff --git "a/2019.04.12 \343\200\214\345\260\217\351\251\254\345\223\245\346\212\200\346\234\257\345\221\250\346\212\245\343\200\215- \347\254\254\344\272\214\345\215\201\344\270\211\346\234\237\343\200\212\351\235\242\350\257\225\350\231\220\346\210\221\345\215\203\347\231\276\351\201\215\357\274\214Java \345\271\266\345\217\221\347\234\237\350\256\250\345\216\214\357\274\210\347\273\255\357\274\211\343\200\213/java-concurrency/src/com/imooc/interview/questions/java/concurrency/collection/ArraysAsListMethodQuestion.java" "b/2019.04.12 \343\200\214\345\260\217\351\251\254\345\223\245\346\212\200\346\234\257\345\221\250\346\212\245\343\200\215- \347\254\254\344\272\214\345\215\201\344\270\211\346\234\237\343\200\212\351\235\242\350\257\225\350\231\220\346\210\221\345\215\203\347\231\276\351\201\215\357\274\214Java \345\271\266\345\217\221\347\234\237\350\256\250\345\216\214\357\274\210\347\273\255\357\274\211\343\200\213/java-concurrency/src/com/imooc/interview/questions/java/concurrency/collection/ArraysAsListMethodQuestion.java" new file mode 100644 index 0000000..8f03d93 --- /dev/null +++ "b/2019.04.12 \343\200\214\345\260\217\351\251\254\345\223\245\346\212\200\346\234\257\345\221\250\346\212\245\343\200\215- \347\254\254\344\272\214\345\215\201\344\270\211\346\234\237\343\200\212\351\235\242\350\257\225\350\231\220\346\210\221\345\215\203\347\231\276\351\201\215\357\274\214Java \345\271\266\345\217\221\347\234\237\350\256\250\345\216\214\357\274\210\347\273\255\357\274\211\343\200\213/java-concurrency/src/com/imooc/interview/questions/java/concurrency/collection/ArraysAsListMethodQuestion.java" @@ -0,0 +1,20 @@ +package com.imooc.interview.questions.java.concurrency.collection; + +import java.util.Arrays; +import java.util.List; + +public class ArraysAsListMethodQuestion { + + public static void main(String[] args) { + + List list = Arrays.asList(1, 2, 3, 4, 5); + // 调整第三个元素为 9 + list.set(2, 9); + // 3 -> 9 + // Arrays.asList 并非线程安全 + list.forEach(System.out::println); + // Java < 5 , Collections#synchronizedList + // Java 5+ , CopyOnWriteArrayList + // Java 9+ , List.of(...) 只读 + } +} diff --git "a/2019.04.12 \343\200\214\345\260\217\351\251\254\345\223\245\346\212\200\346\234\257\345\221\250\346\212\245\343\200\215- \347\254\254\344\272\214\345\215\201\344\270\211\346\234\237\343\200\212\351\235\242\350\257\225\350\231\220\346\210\221\345\215\203\347\231\276\351\201\215\357\274\214Java \345\271\266\345\217\221\347\234\237\350\256\250\345\216\214\357\274\210\347\273\255\357\274\211\343\200\213/java-concurrency/src/com/imooc/interview/questions/java/concurrency/collection/BlockingQueueQuiz.java" "b/2019.04.12 \343\200\214\345\260\217\351\251\254\345\223\245\346\212\200\346\234\257\345\221\250\346\212\245\343\200\215- \347\254\254\344\272\214\345\215\201\344\270\211\346\234\237\343\200\212\351\235\242\350\257\225\350\231\220\346\210\221\345\215\203\347\231\276\351\201\215\357\274\214Java \345\271\266\345\217\221\347\234\237\350\256\250\345\216\214\357\274\210\347\273\255\357\274\211\343\200\213/java-concurrency/src/com/imooc/interview/questions/java/concurrency/collection/BlockingQueueQuiz.java" new file mode 100644 index 0000000..87093bc --- /dev/null +++ "b/2019.04.12 \343\200\214\345\260\217\351\251\254\345\223\245\346\212\200\346\234\257\345\221\250\346\212\245\343\200\215- \347\254\254\344\272\214\345\215\201\344\270\211\346\234\237\343\200\212\351\235\242\350\257\225\350\231\220\346\210\221\345\215\203\347\231\276\351\201\215\357\274\214Java \345\271\266\345\217\221\347\234\237\350\256\250\345\216\214\357\274\210\347\273\255\357\274\211\343\200\213/java-concurrency/src/com/imooc/interview/questions/java/concurrency/collection/BlockingQueueQuiz.java" @@ -0,0 +1,22 @@ +package com.imooc.interview.questions.java.concurrency.collection; + +import java.util.concurrent.*; + +public class BlockingQueueQuiz { + + public static void main(String[] args) throws Exception { + offer(new ArrayBlockingQueue<>(2)); + offer(new LinkedBlockingQueue<>(2)); + offer(new PriorityBlockingQueue<>(2)); + offer(new SynchronousQueue<>()); + } + + private static void offer(BlockingQueue queue) throws Exception { + System.out.println("queue.getClass() = " + queue.getClass().getName()); + System.out.println("queue.offer(1) = " + queue.offer(1)); + System.out.println("queue.offer(2) = " + queue.offer(2)); + System.out.println("queue.offer(3) = " + queue.offer(3)); + System.out.println("queue.size() = " + queue.size()); + System.out.println("queue.take() = " + queue.take()); + } +} diff --git "a/2019.04.12 \343\200\214\345\260\217\351\251\254\345\223\245\346\212\200\346\234\257\345\221\250\346\212\245\343\200\215- \347\254\254\344\272\214\345\215\201\344\270\211\346\234\237\343\200\212\351\235\242\350\257\225\350\231\220\346\210\221\345\215\203\347\231\276\351\201\215\357\274\214Java \345\271\266\345\217\221\347\234\237\350\256\250\345\216\214\357\274\210\347\273\255\357\274\211\343\200\213/java-concurrency/src/com/imooc/interview/questions/java/concurrency/collection/ConcurrentHashSetQuestion.java" "b/2019.04.12 \343\200\214\345\260\217\351\251\254\345\223\245\346\212\200\346\234\257\345\221\250\346\212\245\343\200\215- \347\254\254\344\272\214\345\215\201\344\270\211\346\234\237\343\200\212\351\235\242\350\257\225\350\231\220\346\210\221\345\215\203\347\231\276\351\201\215\357\274\214Java \345\271\266\345\217\221\347\234\237\350\256\250\345\216\214\357\274\210\347\273\255\357\274\211\343\200\213/java-concurrency/src/com/imooc/interview/questions/java/concurrency/collection/ConcurrentHashSetQuestion.java" new file mode 100644 index 0000000..703ed6a --- /dev/null +++ "b/2019.04.12 \343\200\214\345\260\217\351\251\254\345\223\245\346\212\200\346\234\257\345\221\250\346\212\245\343\200\215- \347\254\254\344\272\214\345\215\201\344\270\211\346\234\237\343\200\212\351\235\242\350\257\225\350\231\220\346\210\221\345\215\203\347\231\276\351\201\215\357\274\214Java \345\271\266\345\217\221\347\234\237\350\256\250\345\216\214\357\274\210\347\273\255\357\274\211\343\200\213/java-concurrency/src/com/imooc/interview/questions/java/concurrency/collection/ConcurrentHashSetQuestion.java" @@ -0,0 +1,91 @@ +package com.imooc.interview.questions.java.concurrency.collection; + +import java.util.AbstractSet; +import java.util.Collection; +import java.util.Iterator; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; + +public class ConcurrentHashSetQuestion { + + + public static void main(String[] args) { + + } + + private static class ConcurrentHashSet implements Set { + + private final Object OBJECT = new Object(); + + private final ConcurrentHashMap map = new ConcurrentHashMap<>(); + + private Set keySet() { + return map.keySet(); + } + + @Override + public int size() { + return keySet().size(); + } + + @Override + public boolean isEmpty() { + return keySet().isEmpty(); + } + + @Override + public boolean contains(Object o) { + return keySet().contains(o); + } + + @Override + public Iterator iterator() { + return keySet().iterator(); + } + + @Override + public Object[] toArray() { + return new Object[0]; + } + + @Override + public T[] toArray(T[] a) { + return null; + } + + @Override + public boolean add(E e) { + return map.put(e, OBJECT) == null; + } + + @Override + public boolean remove(Object o) { + return map.remove(o) != null; + } + + @Override + public boolean containsAll(Collection c) { + return false; + } + + @Override + public boolean addAll(Collection c) { + return false; + } + + @Override + public boolean retainAll(Collection c) { + return false; + } + + @Override + public boolean removeAll(Collection c) { + return false; + } + + @Override + public void clear() { + + } + } +} diff --git "a/2019.04.12 \343\200\214\345\260\217\351\251\254\345\223\245\346\212\200\346\234\257\345\221\250\346\212\245\343\200\215- \347\254\254\344\272\214\345\215\201\344\270\211\346\234\237\343\200\212\351\235\242\350\257\225\350\231\220\346\210\221\345\215\203\347\231\276\351\201\215\357\274\214Java \345\271\266\345\217\221\347\234\237\350\256\250\345\216\214\357\274\210\347\273\255\357\274\211\343\200\213/java-concurrency/src/com/imooc/interview/questions/java/concurrency/collection/PriorityBlockingQueueQuiz.java" "b/2019.04.12 \343\200\214\345\260\217\351\251\254\345\223\245\346\212\200\346\234\257\345\221\250\346\212\245\343\200\215- \347\254\254\344\272\214\345\215\201\344\270\211\346\234\237\343\200\212\351\235\242\350\257\225\350\231\220\346\210\221\345\215\203\347\231\276\351\201\215\357\274\214Java \345\271\266\345\217\221\347\234\237\350\256\250\345\216\214\357\274\210\347\273\255\357\274\211\343\200\213/java-concurrency/src/com/imooc/interview/questions/java/concurrency/collection/PriorityBlockingQueueQuiz.java" new file mode 100644 index 0000000..4380acd --- /dev/null +++ "b/2019.04.12 \343\200\214\345\260\217\351\251\254\345\223\245\346\212\200\346\234\257\345\221\250\346\212\245\343\200\215- \347\254\254\344\272\214\345\215\201\344\270\211\346\234\237\343\200\212\351\235\242\350\257\225\350\231\220\346\210\221\345\215\203\347\231\276\351\201\215\357\274\214Java \345\271\266\345\217\221\347\234\237\350\256\250\345\216\214\357\274\210\347\273\255\357\274\211\343\200\213/java-concurrency/src/com/imooc/interview/questions/java/concurrency/collection/PriorityBlockingQueueQuiz.java" @@ -0,0 +1,21 @@ +package com.imooc.interview.questions.java.concurrency.collection; + +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.PriorityBlockingQueue; + +public class PriorityBlockingQueueQuiz { + + public static void main(String[] args) throws Exception { + BlockingQueue queue = new PriorityBlockingQueue<>(2); + // 1. PriorityBlockingQueue put(Object) 方法不阻塞 + // 2. PriorityBlockingQueue offer(Object) 方法不限制 + // 3. PriorityBlockingQueue 插入对象会做排序,默认参照元素 Comparable 实现, + // 或者显示地传递 Comparator + queue.put(9); + queue.put(1); + queue.put(8); + System.out.println("queue.size() = " + queue.size()); + System.out.println("queue.take() = " + queue.take()); + System.out.println("queue = " + queue); + } +} diff --git "a/2019.04.12 \343\200\214\345\260\217\351\251\254\345\223\245\346\212\200\346\234\257\345\221\250\346\212\245\343\200\215- \347\254\254\344\272\214\345\215\201\344\270\211\346\234\237\343\200\212\351\235\242\350\257\225\350\231\220\346\210\221\345\215\203\347\231\276\351\201\215\357\274\214Java \345\271\266\345\217\221\347\234\237\350\256\250\345\216\214\357\274\210\347\273\255\357\274\211\343\200\213/java-concurrency/src/com/imooc/interview/questions/java/concurrency/collection/SynchronousQueueQuiz.java" "b/2019.04.12 \343\200\214\345\260\217\351\251\254\345\223\245\346\212\200\346\234\257\345\221\250\346\212\245\343\200\215- \347\254\254\344\272\214\345\215\201\344\270\211\346\234\237\343\200\212\351\235\242\350\257\225\350\231\220\346\210\221\345\215\203\347\231\276\351\201\215\357\274\214Java \345\271\266\345\217\221\347\234\237\350\256\250\345\216\214\357\274\210\347\273\255\357\274\211\343\200\213/java-concurrency/src/com/imooc/interview/questions/java/concurrency/collection/SynchronousQueueQuiz.java" new file mode 100644 index 0000000..fca6f54 --- /dev/null +++ "b/2019.04.12 \343\200\214\345\260\217\351\251\254\345\223\245\346\212\200\346\234\257\345\221\250\346\212\245\343\200\215- \347\254\254\344\272\214\345\215\201\344\270\211\346\234\237\343\200\212\351\235\242\350\257\225\350\231\220\346\210\221\345\215\203\347\231\276\351\201\215\357\274\214Java \345\271\266\345\217\221\347\234\237\350\256\250\345\216\214\357\274\210\347\273\255\357\274\211\343\200\213/java-concurrency/src/com/imooc/interview/questions/java/concurrency/collection/SynchronousQueueQuiz.java" @@ -0,0 +1,18 @@ +package com.imooc.interview.questions.java.concurrency.collection; + +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.SynchronousQueue; + +public class SynchronousQueueQuiz { + + public static void main(String[] args) throws Exception { + BlockingQueue queue = new SynchronousQueue<>(); + // 1. SynchronousQueue 是无空间,offer 永远返回 false + // 2. SynchronousQueue take() 方法会被阻塞,必须被其他线程显示地调用 put(Object); + System.out.println("queue.offer(1) = " + queue.offer(1)); + System.out.println("queue.offer(2) = " + queue.offer(2)); + System.out.println("queue.offer(3) = " + queue.offer(3)); + System.out.println("queue.take() = " + queue.take()); + System.out.println("queue.size = " + queue.size()); + } +} diff --git "a/2019.04.12 \343\200\214\345\260\217\351\251\254\345\223\245\346\212\200\346\234\257\345\221\250\346\212\245\343\200\215- \347\254\254\344\272\214\345\215\201\344\270\211\346\234\237\343\200\212\351\235\242\350\257\225\350\231\220\346\210\221\345\215\203\347\231\276\351\201\215\357\274\214Java \345\271\266\345\217\221\347\234\237\350\256\250\345\216\214\357\274\210\347\273\255\357\274\211\343\200\213/java-concurrency/src/com/imooc/interview/questions/java/concurrency/collection/ThreadSafeCollectionQuestion.java" "b/2019.04.12 \343\200\214\345\260\217\351\251\254\345\223\245\346\212\200\346\234\257\345\221\250\346\212\245\343\200\215- \347\254\254\344\272\214\345\215\201\344\270\211\346\234\237\343\200\212\351\235\242\350\257\225\350\231\220\346\210\221\345\215\203\347\231\276\351\201\215\357\274\214Java \345\271\266\345\217\221\347\234\237\350\256\250\345\216\214\357\274\210\347\273\255\357\274\211\343\200\213/java-concurrency/src/com/imooc/interview/questions/java/concurrency/collection/ThreadSafeCollectionQuestion.java" new file mode 100644 index 0000000..0c0dc2e --- /dev/null +++ "b/2019.04.12 \343\200\214\345\260\217\351\251\254\345\223\245\346\212\200\346\234\257\345\221\250\346\212\245\343\200\215- \347\254\254\344\272\214\345\215\201\344\270\211\346\234\237\343\200\212\351\235\242\350\257\225\350\231\220\346\210\221\345\215\203\347\231\276\351\201\215\357\274\214Java \345\271\266\345\217\221\347\234\237\350\256\250\345\216\214\357\274\210\347\273\255\357\274\211\343\200\213/java-concurrency/src/com/imooc/interview/questions/java/concurrency/collection/ThreadSafeCollectionQuestion.java" @@ -0,0 +1,40 @@ +package com.imooc.interview.questions.java.concurrency.collection; + +import java.util.*; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.CopyOnWriteArrayList; +import java.util.concurrent.CopyOnWriteArraySet; + +public class ThreadSafeCollectionQuestion { + + public static void main(String[] args) { + + // Java 9 的实现 + List list = Arrays.asList(1, 2, 3, 4, 5); + + // Java 9 + of 工厂方法,返回 Immutable 对象 + + list = List.of(1, 2, 3, 4, 5); + + Set set = Set.of(1, 2, 3, 4, 5); + + Map map = Map.of(1, "A"); + + // 以上实现都是不变对象,不过第一个除外 + + // 通过 Collections#sychronized* 方法返回 + + // Wrapper 设计模式(所有的方法都被 synchronized 同步或互斥) + list = Collections.synchronizedList(list); + + set = Collections.synchronizedSet(set); + + map = Collections.synchronizedMap(map); + + // + list = new CopyOnWriteArrayList<>(list); + set = new CopyOnWriteArraySet<>(set); + map = new ConcurrentHashMap<>(map); + + } +} diff --git "a/2019.04.12 \343\200\214\345\260\217\351\251\254\345\223\245\346\212\200\346\234\257\345\221\250\346\212\245\343\200\215- \347\254\254\344\272\214\345\215\201\344\270\211\346\234\237\343\200\212\351\235\242\350\257\225\350\231\220\346\210\221\345\215\203\347\231\276\351\201\215\357\274\214Java \345\271\266\345\217\221\347\234\237\350\256\250\345\216\214\357\274\210\347\273\255\357\274\211\343\200\213/java-concurrency/src/com/imooc/interview/questions/java/concurrency/future/CancellableFutureQuestion.java" "b/2019.04.12 \343\200\214\345\260\217\351\251\254\345\223\245\346\212\200\346\234\257\345\221\250\346\212\245\343\200\215- \347\254\254\344\272\214\345\215\201\344\270\211\346\234\237\343\200\212\351\235\242\350\257\225\350\231\220\346\210\221\345\215\203\347\231\276\351\201\215\357\274\214Java \345\271\266\345\217\221\347\234\237\350\256\250\345\216\214\357\274\210\347\273\255\357\274\211\343\200\213/java-concurrency/src/com/imooc/interview/questions/java/concurrency/future/CancellableFutureQuestion.java" new file mode 100644 index 0000000..06259a3 --- /dev/null +++ "b/2019.04.12 \343\200\214\345\260\217\351\251\254\345\223\245\346\212\200\346\234\257\345\221\250\346\212\245\343\200\215- \347\254\254\344\272\214\345\215\201\344\270\211\346\234\237\343\200\212\351\235\242\350\257\225\350\231\220\346\210\221\345\215\203\347\231\276\351\201\215\357\274\214Java \345\271\266\345\217\221\347\234\237\350\256\250\345\216\214\357\274\210\347\273\255\357\274\211\343\200\213/java-concurrency/src/com/imooc/interview/questions/java/concurrency/future/CancellableFutureQuestion.java" @@ -0,0 +1,47 @@ +package com.imooc.interview.questions.java.concurrency.future; + +import java.util.concurrent.*; + +public class CancellableFutureQuestion { + + public static void main(String[] args) { + + ExecutorService executorService = Executors.newSingleThreadExecutor(); + + Future future = executorService.submit(() -> { // 3秒内执行完成,才算正常 + action(5); + }); + + try { + future.get(3, TimeUnit.SECONDS); + } catch (InterruptedException e) { + // Thread 恢复中断状态 + Thread.currentThread().interrupt(); + } catch (ExecutionException e) { + throw new RuntimeException(e); + } catch (TimeoutException e) { + // 执行超时,适当地关闭 + Thread.currentThread().interrupt(); // 设置中断状态 + future.cancel(true); // 尝试取消 + } + + executorService.shutdown(); + } + + private static void action(int seconds) { + try { + Thread.sleep(TimeUnit.SECONDS.toMillis(seconds)); // 5 - 3 + // seconds - timeout = 剩余执行时间 + if (Thread.interrupted()) { // 判断并且清除中断状态 + return; + } + action(); + } catch (InterruptedException e) { + } + } + + private static void action() { + System.out.printf("线程[%s] 正在执行...\n", Thread.currentThread().getName()); // 2 + } + +} diff --git "a/2019.04.12 \343\200\214\345\260\217\351\251\254\345\223\245\346\212\200\346\234\257\345\221\250\346\212\245\343\200\215- \347\254\254\344\272\214\345\215\201\344\270\211\346\234\237\343\200\212\351\235\242\350\257\225\350\231\220\346\210\221\345\215\203\347\231\276\351\201\215\357\274\214Java \345\271\266\345\217\221\347\234\237\350\256\250\345\216\214\357\274\210\347\273\255\357\274\211\343\200\213/java-concurrency/src/com/imooc/interview/questions/java/concurrency/lock/ReentrantLockQuestion.java" "b/2019.04.12 \343\200\214\345\260\217\351\251\254\345\223\245\346\212\200\346\234\257\345\221\250\346\212\245\343\200\215- \347\254\254\344\272\214\345\215\201\344\270\211\346\234\237\343\200\212\351\235\242\350\257\225\350\231\220\346\210\221\345\215\203\347\231\276\351\201\215\357\274\214Java \345\271\266\345\217\221\347\234\237\350\256\250\345\216\214\357\274\210\347\273\255\357\274\211\343\200\213/java-concurrency/src/com/imooc/interview/questions/java/concurrency/lock/ReentrantLockQuestion.java" new file mode 100644 index 0000000..b6769e8 --- /dev/null +++ "b/2019.04.12 \343\200\214\345\260\217\351\251\254\345\223\245\346\212\200\346\234\257\345\221\250\346\212\245\343\200\215- \347\254\254\344\272\214\345\215\201\344\270\211\346\234\237\343\200\212\351\235\242\350\257\225\350\231\220\346\210\221\345\215\203\347\231\276\351\201\215\357\274\214Java \345\271\266\345\217\221\347\234\237\350\256\250\345\216\214\357\274\210\347\273\255\357\274\211\343\200\213/java-concurrency/src/com/imooc/interview/questions/java/concurrency/lock/ReentrantLockQuestion.java" @@ -0,0 +1,78 @@ +package com.imooc.interview.questions.java.concurrency.lock; + +import java.util.concurrent.locks.ReentrantLock; + +public class ReentrantLockQuestion { + + /** + * T1 , T2 , T3 + * + * T1(lock) , T2(park), T3(park) + * Waited Queue -> Head-> T2 next -> T3 + * T1(unlock) -> unpark all + * Waited Queue -> Head-> T2 next -> T3 + * T2(free), T3(free) + * + * -> T2(lock) , T3(park) + * Waited Queue -> Head-> T3 + * T2(unlock) -> unpark all + * T3(free) + */ + + + /** + * java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireQueued + * 如果当前线程已被其他线程调用了 interrupt() 方法时,这时会返回 true + * acquireQueued 执行完时,interrupt 清空(false) + * 再通过 selfInterrupt() 方法将状态恢复(interrupt=true) + */ + + + private static ReentrantLock lock = new ReentrantLock(); + + public static void main(String[] args) { + // thread[main] -> + // lock lock lock + // main -> action1() -> action2() -> action3() + synchronizedAction(ReentrantLockQuestion::action1); + + lockVsLockInterruptibly(); + } + + private static void lockVsLockInterruptibly() { + + try { + lock.lockInterruptibly(); + action1(); + } catch (InterruptedException e) { + // 显示地恢复中断状态 + Thread.currentThread().interrupt(); + // 当前线程并未消亡,线程池可能还在存活 + } finally { + lock.unlock(); + } + } + + + private static void action1() { + synchronizedAction(ReentrantLockQuestion::action2); + + } + + private static void action2() { + synchronizedAction(ReentrantLockQuestion::action3); + } + + private static void action3() { + System.out.println("Hello,World"); + } + + private static void synchronizedAction(Runnable runnable) { + lock.lock(); + try { + runnable.run(); + } finally { + lock.unlock(); + } + } +} diff --git "a/2019.04.12 \343\200\214\345\260\217\351\251\254\345\223\245\346\212\200\346\234\257\345\221\250\346\212\245\343\200\215- \347\254\254\344\272\214\345\215\201\344\270\211\346\234\237\343\200\212\351\235\242\350\257\225\350\231\220\346\210\221\345\215\203\347\231\276\351\201\215\357\274\214Java \345\271\266\345\217\221\347\234\237\350\256\250\345\216\214\357\274\210\347\273\255\357\274\211\343\200\213/java-concurrency/src/com/imooc/interview/questions/java/concurrency/thread/AllThreadInfoQuestion.java" "b/2019.04.12 \343\200\214\345\260\217\351\251\254\345\223\245\346\212\200\346\234\257\345\221\250\346\212\245\343\200\215- \347\254\254\344\272\214\345\215\201\344\270\211\346\234\237\343\200\212\351\235\242\350\257\225\350\231\220\346\210\221\345\215\203\347\231\276\351\201\215\357\274\214Java \345\271\266\345\217\221\347\234\237\350\256\250\345\216\214\357\274\210\347\273\255\357\274\211\343\200\213/java-concurrency/src/com/imooc/interview/questions/java/concurrency/thread/AllThreadInfoQuestion.java" new file mode 100644 index 0000000..a5e407f --- /dev/null +++ "b/2019.04.12 \343\200\214\345\260\217\351\251\254\345\223\245\346\212\200\346\234\257\345\221\250\346\212\245\343\200\215- \347\254\254\344\272\214\345\215\201\344\270\211\346\234\237\343\200\212\351\235\242\350\257\225\350\231\220\346\210\221\345\215\203\347\231\276\351\201\215\357\274\214Java \345\271\266\345\217\221\347\234\237\350\256\250\345\216\214\357\274\210\347\273\255\357\274\211\343\200\213/java-concurrency/src/com/imooc/interview/questions/java/concurrency/thread/AllThreadInfoQuestion.java" @@ -0,0 +1,23 @@ +package com.imooc.interview.questions.java.concurrency.thread; + +import com.sun.management.ThreadMXBean; + +import java.lang.management.ManagementFactory; +import java.lang.management.ThreadInfo; + +public class AllThreadInfoQuestion { + + public static void main(String[] args) { + ThreadMXBean threadMXBean = (ThreadMXBean) ManagementFactory.getThreadMXBean(); + long[] threadIds = threadMXBean.getAllThreadIds(); + + for (long threadId : threadIds) { +// ThreadInfo threadInfo = threadMXBean.getThreadInfo(threadId); +// System.out.println(threadInfo.toString()); + long bytes = threadMXBean.getThreadAllocatedBytes(threadId); + long kBytes = bytes / 1024; + System.out.printf("线程[ID:%d] 分配内存: %s KB\n", threadId, kBytes); + } + + } +} diff --git "a/2019.04.12 \343\200\214\345\260\217\351\251\254\345\223\245\346\212\200\346\234\257\345\221\250\346\212\245\343\200\215- \347\254\254\344\272\214\345\215\201\344\270\211\346\234\237\343\200\212\351\235\242\350\257\225\350\231\220\346\210\221\345\215\203\347\231\276\351\201\215\357\274\214Java \345\271\266\345\217\221\347\234\237\350\256\250\345\216\214\357\274\210\347\273\255\357\274\211\343\200\213/java-concurrency/src/com/imooc/interview/questions/java/concurrency/thread/AllThreadStackQuestion.java" "b/2019.04.12 \343\200\214\345\260\217\351\251\254\345\223\245\346\212\200\346\234\257\345\221\250\346\212\245\343\200\215- \347\254\254\344\272\214\345\215\201\344\270\211\346\234\237\343\200\212\351\235\242\350\257\225\350\231\220\346\210\221\345\215\203\347\231\276\351\201\215\357\274\214Java \345\271\266\345\217\221\347\234\237\350\256\250\345\216\214\357\274\210\347\273\255\357\274\211\343\200\213/java-concurrency/src/com/imooc/interview/questions/java/concurrency/thread/AllThreadStackQuestion.java" new file mode 100644 index 0000000..e9f4192 --- /dev/null +++ "b/2019.04.12 \343\200\214\345\260\217\351\251\254\345\223\245\346\212\200\346\234\257\345\221\250\346\212\245\343\200\215- \347\254\254\344\272\214\345\215\201\344\270\211\346\234\237\343\200\212\351\235\242\350\257\225\350\231\220\346\210\221\345\215\203\347\231\276\351\201\215\357\274\214Java \345\271\266\345\217\221\347\234\237\350\256\250\345\216\214\357\274\210\347\273\255\357\274\211\343\200\213/java-concurrency/src/com/imooc/interview/questions/java/concurrency/thread/AllThreadStackQuestion.java" @@ -0,0 +1,20 @@ +package com.imooc.interview.questions.java.concurrency.thread; + +import java.lang.management.ManagementFactory; +import java.lang.management.ThreadInfo; +import java.lang.management.ThreadMXBean; +import java.util.stream.Stream; + +public class AllThreadStackQuestion { + + public static void main(String[] args) { + ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean(); + long[] threadIds = threadMXBean.getAllThreadIds(); + + for (long threadId : threadIds) { + ThreadInfo threadInfo = threadMXBean.getThreadInfo(threadId); + System.out.println(threadInfo.toString()); + } + + } +} diff --git "a/2019.04.12 \343\200\214\345\260\217\351\251\254\345\223\245\346\212\200\346\234\257\345\221\250\346\212\245\343\200\215- \347\254\254\344\272\214\345\215\201\344\270\211\346\234\237\343\200\212\351\235\242\350\257\225\350\231\220\346\210\221\345\215\203\347\231\276\351\201\215\357\274\214Java \345\271\266\345\217\221\347\234\237\350\256\250\345\216\214\357\274\210\347\273\255\357\274\211\343\200\213/java-concurrency/src/com/imooc/interview/questions/java/concurrency/thread/CompleteAllThreadsQuestion.java" "b/2019.04.12 \343\200\214\345\260\217\351\251\254\345\223\245\346\212\200\346\234\257\345\221\250\346\212\245\343\200\215- \347\254\254\344\272\214\345\215\201\344\270\211\346\234\237\343\200\212\351\235\242\350\257\225\350\231\220\346\210\221\345\215\203\347\231\276\351\201\215\357\274\214Java \345\271\266\345\217\221\347\234\237\350\256\250\345\216\214\357\274\210\347\273\255\357\274\211\343\200\213/java-concurrency/src/com/imooc/interview/questions/java/concurrency/thread/CompleteAllThreadsQuestion.java" new file mode 100644 index 0000000..3820708 --- /dev/null +++ "b/2019.04.12 \343\200\214\345\260\217\351\251\254\345\223\245\346\212\200\346\234\257\345\221\250\346\212\245\343\200\215- \347\254\254\344\272\214\345\215\201\344\270\211\346\234\237\343\200\212\351\235\242\350\257\225\350\231\220\346\210\221\345\215\203\347\231\276\351\201\215\357\274\214Java \345\271\266\345\217\221\347\234\237\350\256\250\345\216\214\357\274\210\347\273\255\357\274\211\343\200\213/java-concurrency/src/com/imooc/interview/questions/java/concurrency/thread/CompleteAllThreadsQuestion.java" @@ -0,0 +1,38 @@ +package com.imooc.interview.questions.java.concurrency.thread; + +public class CompleteAllThreadsQuestion { + + public static void main(String[] args) throws InterruptedException { + + // main 线程 -> 子线程 + Thread t1 = new Thread(CompleteAllThreadsQuestion::action, "t1"); + Thread t2 = new Thread(CompleteAllThreadsQuestion::action, "t2"); + Thread t3 = new Thread(CompleteAllThreadsQuestion::action, "t3"); + + // 不确定 t1、t2、t3 是否调用 start() + + t1.start(); + t2.start(); + t3.start(); + + // 创建了 N Thread + + Thread mainThread = Thread.currentThread(); + // 获取 main 线程组 + ThreadGroup threadGroup = mainThread.getThreadGroup(); + // 活跃的线程数 + int count = threadGroup.activeCount(); + Thread[] threads = new Thread[count]; + // 把所有的线程复制 threads 数组 + threadGroup.enumerate(threads, true); + + for (Thread thread : threads) { + System.out.printf("当前活跃线程: %s\n", thread.getName()); + } + } + + private static void action() { + System.out.printf("线程[%s] 正在执行...\n", Thread.currentThread().getName()); // 2 + } + +} diff --git "a/2019.04.12 \343\200\214\345\260\217\351\251\254\345\223\245\346\212\200\346\234\257\345\221\250\346\212\245\343\200\215- \347\254\254\344\272\214\345\215\201\344\270\211\346\234\237\343\200\212\351\235\242\350\257\225\350\231\220\346\210\221\345\215\203\347\231\276\351\201\215\357\274\214Java \345\271\266\345\217\221\347\234\237\350\256\250\345\216\214\357\274\210\347\273\255\357\274\211\343\200\213/java-concurrency/src/com/imooc/interview/questions/java/concurrency/thread/DaemonThreadQuestion.java" "b/2019.04.12 \343\200\214\345\260\217\351\251\254\345\223\245\346\212\200\346\234\257\345\221\250\346\212\245\343\200\215- \347\254\254\344\272\214\345\215\201\344\270\211\346\234\237\343\200\212\351\235\242\350\257\225\350\231\220\346\210\221\345\215\203\347\231\276\351\201\215\357\274\214Java \345\271\266\345\217\221\347\234\237\350\256\250\345\216\214\357\274\210\347\273\255\357\274\211\343\200\213/java-concurrency/src/com/imooc/interview/questions/java/concurrency/thread/DaemonThreadQuestion.java" new file mode 100644 index 0000000..2e35d9f --- /dev/null +++ "b/2019.04.12 \343\200\214\345\260\217\351\251\254\345\223\245\346\212\200\346\234\257\345\221\250\346\212\245\343\200\215- \347\254\254\344\272\214\345\215\201\344\270\211\346\234\237\343\200\212\351\235\242\350\257\225\350\231\220\346\210\221\345\215\203\347\231\276\351\201\215\357\274\214Java \345\271\266\345\217\221\347\234\237\350\256\250\345\216\214\357\274\210\347\273\255\357\274\211\343\200\213/java-concurrency/src/com/imooc/interview/questions/java/concurrency/thread/DaemonThreadQuestion.java" @@ -0,0 +1,21 @@ +package com.imooc.interview.questions.java.concurrency.thread; + +public class DaemonThreadQuestion { + + public static void main(String[] args) { + // main 线程 + Thread t1 = new Thread(() -> { + System.out.println("Hello,World"); +// Thread currentThread = Thread.currentThread(); +// System.out.printf("线程[name : %s, daemon:%s]: Hello,World\n", +// currentThread.getName(), +// currentThread.isDaemon() +// ); + }, "daemon"); + // 编程守候线程 + t1.setDaemon(true); + t1.start(); + + // 守候线程的执行依赖于执行时间(非唯一评判) + } +} diff --git "a/2019.04.12 \343\200\214\345\260\217\351\251\254\345\223\245\346\212\200\346\234\257\345\221\250\346\212\245\343\200\215- \347\254\254\344\272\214\345\215\201\344\270\211\346\234\237\343\200\212\351\235\242\350\257\225\350\231\220\346\210\221\345\215\203\347\231\276\351\201\215\357\274\214Java \345\271\266\345\217\221\347\234\237\350\256\250\345\216\214\357\274\210\347\273\255\357\274\211\343\200\213/java-concurrency/src/com/imooc/interview/questions/java/concurrency/thread/HowToStopThreadQuestion.java" "b/2019.04.12 \343\200\214\345\260\217\351\251\254\345\223\245\346\212\200\346\234\257\345\221\250\346\212\245\343\200\215- \347\254\254\344\272\214\345\215\201\344\270\211\346\234\237\343\200\212\351\235\242\350\257\225\350\231\220\346\210\221\345\215\203\347\231\276\351\201\215\357\274\214Java \345\271\266\345\217\221\347\234\237\350\256\250\345\216\214\357\274\210\347\273\255\357\274\211\343\200\213/java-concurrency/src/com/imooc/interview/questions/java/concurrency/thread/HowToStopThreadQuestion.java" new file mode 100644 index 0000000..fd2e7ab --- /dev/null +++ "b/2019.04.12 \343\200\214\345\260\217\351\251\254\345\223\245\346\212\200\346\234\257\345\221\250\346\212\245\343\200\215- \347\254\254\344\272\214\345\215\201\344\270\211\346\234\237\343\200\212\351\235\242\350\257\225\350\231\220\346\210\221\345\215\203\347\231\276\351\201\215\357\274\214Java \345\271\266\345\217\221\347\234\237\350\256\250\345\216\214\357\274\210\347\273\255\357\274\211\343\200\213/java-concurrency/src/com/imooc/interview/questions/java/concurrency/thread/HowToStopThreadQuestion.java" @@ -0,0 +1,53 @@ +package com.imooc.interview.questions.java.concurrency.thread; + +public class HowToStopThreadQuestion { + + public static void main(String[] args) throws InterruptedException { + + Action action = new Action(); + + // 子线程 + Thread t1 = new Thread(action, "t1"); + + t1.start(); + + // 改变 action stopped 状态 + action.setStopped(true); + + t1.join(); + + Thread t2 = new Thread(() -> { + if (!Thread.currentThread().isInterrupted()) { + action(); + } + }, "t2"); + + t2.start(); + // 中断操作(仅仅设置状态,而并非中止线程) + t2.interrupt(); + t2.join(); + } + + + private static class Action implements Runnable { + + // 线程安全问题,确保可见性(Happens-Before) + private volatile boolean stopped = false; + + @Override + public void run() { + if (!stopped) { + // 执行动作 + action(); + } + } + + public void setStopped(boolean stopped) { + this.stopped = stopped; + } + } + + private static void action() { + System.out.printf("线程[%s] 正在执行...\n", Thread.currentThread().getName()); // 2 + } +} diff --git "a/2019.04.12 \343\200\214\345\260\217\351\251\254\345\223\245\346\212\200\346\234\257\345\221\250\346\212\245\343\200\215- \347\254\254\344\272\214\345\215\201\344\270\211\346\234\237\343\200\212\351\235\242\350\257\225\350\231\220\346\210\221\345\215\203\347\231\276\351\201\215\357\274\214Java \345\271\266\345\217\221\347\234\237\350\256\250\345\216\214\357\274\210\347\273\255\357\274\211\343\200\213/java-concurrency/src/com/imooc/interview/questions/java/concurrency/thread/ProcessCreationQuestion.java" "b/2019.04.12 \343\200\214\345\260\217\351\251\254\345\223\245\346\212\200\346\234\257\345\221\250\346\212\245\343\200\215- \347\254\254\344\272\214\345\215\201\344\270\211\346\234\237\343\200\212\351\235\242\350\257\225\350\231\220\346\210\221\345\215\203\347\231\276\351\201\215\357\274\214Java \345\271\266\345\217\221\347\234\237\350\256\250\345\216\214\357\274\210\347\273\255\357\274\211\343\200\213/java-concurrency/src/com/imooc/interview/questions/java/concurrency/thread/ProcessCreationQuestion.java" new file mode 100644 index 0000000..2a143f7 --- /dev/null +++ "b/2019.04.12 \343\200\214\345\260\217\351\251\254\345\223\245\346\212\200\346\234\257\345\221\250\346\212\245\343\200\215- \347\254\254\344\272\214\345\215\201\344\270\211\346\234\237\343\200\212\351\235\242\350\257\225\350\231\220\346\210\221\345\215\203\347\231\276\351\201\215\357\274\214Java \345\271\266\345\217\221\347\234\237\350\256\250\345\216\214\357\274\210\347\273\255\357\274\211\343\200\213/java-concurrency/src/com/imooc/interview/questions/java/concurrency/thread/ProcessCreationQuestion.java" @@ -0,0 +1,14 @@ +package com.imooc.interview.questions.java.concurrency.thread; + +import java.io.IOException; + +public class ProcessCreationQuestion { + + public static void main(String[] args) throws IOException { + + // 获取 Java Runtime + Runtime runtime = Runtime.getRuntime(); + Process process = runtime.exec("cmd /k start http://www.baidu.com"); + process.exitValue(); + } +} diff --git "a/2019.04.12 \343\200\214\345\260\217\351\251\254\345\223\245\346\212\200\346\234\257\345\221\250\346\212\245\343\200\215- \347\254\254\344\272\214\345\215\201\344\270\211\346\234\237\343\200\212\351\235\242\350\257\225\350\231\220\346\210\221\345\215\203\347\231\276\351\201\215\357\274\214Java \345\271\266\345\217\221\347\234\237\350\256\250\345\216\214\357\274\210\347\273\255\357\274\211\343\200\213/java-concurrency/src/com/imooc/interview/questions/java/concurrency/thread/ShutdownHookQuestion.java" "b/2019.04.12 \343\200\214\345\260\217\351\251\254\345\223\245\346\212\200\346\234\257\345\221\250\346\212\245\343\200\215- \347\254\254\344\272\214\345\215\201\344\270\211\346\234\237\343\200\212\351\235\242\350\257\225\350\231\220\346\210\221\345\215\203\347\231\276\351\201\215\357\274\214Java \345\271\266\345\217\221\347\234\237\350\256\250\345\216\214\357\274\210\347\273\255\357\274\211\343\200\213/java-concurrency/src/com/imooc/interview/questions/java/concurrency/thread/ShutdownHookQuestion.java" new file mode 100644 index 0000000..e95de4b --- /dev/null +++ "b/2019.04.12 \343\200\214\345\260\217\351\251\254\345\223\245\346\212\200\346\234\257\345\221\250\346\212\245\343\200\215- \347\254\254\344\272\214\345\215\201\344\270\211\346\234\237\343\200\212\351\235\242\350\257\225\350\231\220\346\210\221\345\215\203\347\231\276\351\201\215\357\274\214Java \345\271\266\345\217\221\347\234\237\350\256\250\345\216\214\357\274\210\347\273\255\357\274\211\343\200\213/java-concurrency/src/com/imooc/interview/questions/java/concurrency/thread/ShutdownHookQuestion.java" @@ -0,0 +1,16 @@ +package com.imooc.interview.questions.java.concurrency.thread; + +public class ShutdownHookQuestion { + + public static void main(String[] args) { + + Runtime runtime = Runtime.getRuntime(); + + runtime.addShutdownHook(new Thread(ShutdownHookQuestion::action, "Shutdown Hook Question")); + + } + + private static void action() { + System.out.printf("线程[%s] 正在执行...\n", Thread.currentThread().getName()); // 2 + } +} diff --git "a/2019.04.12 \343\200\214\345\260\217\351\251\254\345\223\245\346\212\200\346\234\257\345\221\250\346\212\245\343\200\215- \347\254\254\344\272\214\345\215\201\344\270\211\346\234\237\343\200\212\351\235\242\350\257\225\350\231\220\346\210\221\345\215\203\347\231\276\351\201\215\357\274\214Java \345\271\266\345\217\221\347\234\237\350\256\250\345\216\214\357\274\210\347\273\255\357\274\211\343\200\213/java-concurrency/src/com/imooc/interview/questions/java/concurrency/thread/SynchronizedKeywordQuestion.java" "b/2019.04.12 \343\200\214\345\260\217\351\251\254\345\223\245\346\212\200\346\234\257\345\221\250\346\212\245\343\200\215- \347\254\254\344\272\214\345\215\201\344\270\211\346\234\237\343\200\212\351\235\242\350\257\225\350\231\220\346\210\221\345\215\203\347\231\276\351\201\215\357\274\214Java \345\271\266\345\217\221\347\234\237\350\256\250\345\216\214\357\274\210\347\273\255\357\274\211\343\200\213/java-concurrency/src/com/imooc/interview/questions/java/concurrency/thread/SynchronizedKeywordQuestion.java" new file mode 100644 index 0000000..e7396dd --- /dev/null +++ "b/2019.04.12 \343\200\214\345\260\217\351\251\254\345\223\245\346\212\200\346\234\257\345\221\250\346\212\245\343\200\215- \347\254\254\344\272\214\345\215\201\344\270\211\346\234\237\343\200\212\351\235\242\350\257\225\350\231\220\346\210\221\345\215\203\347\231\276\351\201\215\357\274\214Java \345\271\266\345\217\221\347\234\237\350\256\250\345\216\214\357\274\210\347\273\255\357\274\211\343\200\213/java-concurrency/src/com/imooc/interview/questions/java/concurrency/thread/SynchronizedKeywordQuestion.java" @@ -0,0 +1,16 @@ +package com.imooc.interview.questions.java.concurrency.thread; + +public class SynchronizedKeywordQuestion { + + public static void main(String[] args) { + + } + + private static void synchronizedBlock() { + synchronized (SynchronizedKeywordQuestion.class) { + } + } + + private synchronized static void synchronizedMethod() { + } +} diff --git "a/2019.04.12 \343\200\214\345\260\217\351\251\254\345\223\245\346\212\200\346\234\257\345\221\250\346\212\245\343\200\215- \347\254\254\344\272\214\345\215\201\344\270\211\346\234\237\343\200\212\351\235\242\350\257\225\350\231\220\346\210\221\345\215\203\347\231\276\351\201\215\357\274\214Java \345\271\266\345\217\221\347\234\237\350\256\250\345\216\214\357\274\210\347\273\255\357\274\211\343\200\213/java-concurrency/src/com/imooc/interview/questions/java/concurrency/thread/ThreadCreationQuestion.java" "b/2019.04.12 \343\200\214\345\260\217\351\251\254\345\223\245\346\212\200\346\234\257\345\221\250\346\212\245\343\200\215- \347\254\254\344\272\214\345\215\201\344\270\211\346\234\237\343\200\212\351\235\242\350\257\225\350\231\220\346\210\221\345\215\203\347\231\276\351\201\215\357\274\214Java \345\271\266\345\217\221\347\234\237\350\256\250\345\216\214\357\274\210\347\273\255\357\274\211\343\200\213/java-concurrency/src/com/imooc/interview/questions/java/concurrency/thread/ThreadCreationQuestion.java" new file mode 100644 index 0000000..e3fcf2b --- /dev/null +++ "b/2019.04.12 \343\200\214\345\260\217\351\251\254\345\223\245\346\212\200\346\234\257\345\221\250\346\212\245\343\200\215- \347\254\254\344\272\214\345\215\201\344\270\211\346\234\237\343\200\212\351\235\242\350\257\225\350\231\220\346\210\221\345\215\203\347\231\276\351\201\215\357\274\214Java \345\271\266\345\217\221\347\234\237\350\256\250\345\216\214\357\274\210\347\273\255\357\274\211\343\200\213/java-concurrency/src/com/imooc/interview/questions/java/concurrency/thread/ThreadCreationQuestion.java" @@ -0,0 +1,26 @@ +package com.imooc.interview.questions.java.concurrency.thread; + +public class ThreadCreationQuestion { + + public static void main(String[] args) { + // main 线程 -> 子线程 + Thread thread = new Thread(() -> { + }, "子线程-1"); + + } + + /** + * 不鼓励自定义(扩展) Thread + */ + private static class MyThread extends Thread { + + /** + * 多态的方式,覆盖父类实现 + */ + @Override + public void run(){ + super.run(); + } + } + +} diff --git "a/2019.04.12 \343\200\214\345\260\217\351\251\254\345\223\245\346\212\200\346\234\257\345\221\250\346\212\245\343\200\215- \347\254\254\344\272\214\345\215\201\344\270\211\346\234\237\343\200\212\351\235\242\350\257\225\350\231\220\346\210\221\345\215\203\347\231\276\351\201\215\357\274\214Java \345\271\266\345\217\221\347\234\237\350\256\250\345\216\214\357\274\210\347\273\255\357\274\211\343\200\213/java-concurrency/src/com/imooc/interview/questions/java/concurrency/thread/ThreadExceptionQuestion.java" "b/2019.04.12 \343\200\214\345\260\217\351\251\254\345\223\245\346\212\200\346\234\257\345\221\250\346\212\245\343\200\215- \347\254\254\344\272\214\345\215\201\344\270\211\346\234\237\343\200\212\351\235\242\350\257\225\350\231\220\346\210\221\345\215\203\347\231\276\351\201\215\357\274\214Java \345\271\266\345\217\221\347\234\237\350\256\250\345\216\214\357\274\210\347\273\255\357\274\211\343\200\213/java-concurrency/src/com/imooc/interview/questions/java/concurrency/thread/ThreadExceptionQuestion.java" new file mode 100644 index 0000000..d916484 --- /dev/null +++ "b/2019.04.12 \343\200\214\345\260\217\351\251\254\345\223\245\346\212\200\346\234\257\345\221\250\346\212\245\343\200\215- \347\254\254\344\272\214\345\215\201\344\270\211\346\234\237\343\200\212\351\235\242\350\257\225\350\231\220\346\210\221\345\215\203\347\231\276\351\201\215\357\274\214Java \345\271\266\345\217\221\347\234\237\350\256\250\345\216\214\357\274\210\347\273\255\357\274\211\343\200\213/java-concurrency/src/com/imooc/interview/questions/java/concurrency/thread/ThreadExceptionQuestion.java" @@ -0,0 +1,27 @@ +package com.imooc.interview.questions.java.concurrency.thread; + +public class ThreadExceptionQuestion { + + public static void main(String[] args) throws InterruptedException { + + Thread.setDefaultUncaughtExceptionHandler((thread, throwable) -> { + System.out.printf("线程[%s] 遇到了异常,详细信息:%s\n", + thread.getName(), + throwable.getMessage()); + }); + + // main 线程 -> 子线程 + Thread t1 = new Thread(() -> { + throw new RuntimeException("数据达到阈值"); + }, "t1"); + + t1.start(); + // main 线程会中止吗? + t1.join(); + + // Java Thread 是一个包装,它由 GC 做垃圾回收 + // JVM Thread 可能是一个 OS Thread,JVM 管理, + // 当线程执行完毕(正常或者异常) + System.out.println(t1.isAlive()); + } +} diff --git "a/2019.04.12 \343\200\214\345\260\217\351\251\254\345\223\245\346\212\200\346\234\257\345\221\250\346\212\245\343\200\215- \347\254\254\344\272\214\345\215\201\344\270\211\346\234\237\343\200\212\351\235\242\350\257\225\350\231\220\346\210\221\345\215\203\347\231\276\351\201\215\357\274\214Java \345\271\266\345\217\221\347\234\237\350\256\250\345\216\214\357\274\210\347\273\255\357\274\211\343\200\213/java-concurrency/src/com/imooc/interview/questions/java/concurrency/thread/ThreadExecutionQuestion.java" "b/2019.04.12 \343\200\214\345\260\217\351\251\254\345\223\245\346\212\200\346\234\257\345\221\250\346\212\245\343\200\215- \347\254\254\344\272\214\345\215\201\344\270\211\346\234\237\343\200\212\351\235\242\350\257\225\350\231\220\346\210\221\345\215\203\347\231\276\351\201\215\357\274\214Java \345\271\266\345\217\221\347\234\237\350\256\250\345\216\214\357\274\210\347\273\255\357\274\211\343\200\213/java-concurrency/src/com/imooc/interview/questions/java/concurrency/thread/ThreadExecutionQuestion.java" new file mode 100644 index 0000000..91c23f7 --- /dev/null +++ "b/2019.04.12 \343\200\214\345\260\217\351\251\254\345\223\245\346\212\200\346\234\257\345\221\250\346\212\245\343\200\215- \347\254\254\344\272\214\345\215\201\344\270\211\346\234\237\343\200\212\351\235\242\350\257\225\350\231\220\346\210\221\345\215\203\347\231\276\351\201\215\357\274\214Java \345\271\266\345\217\221\347\234\237\350\256\250\345\216\214\357\274\210\347\273\255\357\274\211\343\200\213/java-concurrency/src/com/imooc/interview/questions/java/concurrency/thread/ThreadExecutionQuestion.java" @@ -0,0 +1,118 @@ +package com.imooc.interview.questions.java.concurrency.thread; + +public class ThreadExecutionQuestion { + + public static void main(String[] args) throws InterruptedException { + + + threadWait(); + } + + private static void threadWait() throws InterruptedException { + + Thread t1 = new Thread(ThreadExecutionQuestion::action, "t1"); + Thread t2 = new Thread(ThreadExecutionQuestion::action, "t2"); + Thread t3 = new Thread(ThreadExecutionQuestion::action, "t3"); + + threadStartAndWait(t1); + threadStartAndWait(t2); + threadStartAndWait(t3); + } + + private static void threadStartAndWait(Thread thread) { + + if (Thread.State.NEW.equals(thread.getState())) { + thread.start(); + } + + // Java Thread 对象和实际 JVM 执行的 OS Thread 不是相同对象 + // JVM Thread 回调 Java Thread.run() 方法, + // 同时 Thread 提供一些 native 方法来获取 JVM Thread 状态 + // 当 JVM Thread 执行后,自动就 notify() 了 + while (thread.isAlive()) { // Thread 特殊的 Object + // 当线程 Thread isAlive() == false 时,thread.wait() 操作会被自动释放 + synchronized (thread) { + try { + thread.wait(); // 到底是谁通知 Thread -> thread.notify(); +// LockSupport.park(); // 死锁发生 + } catch (Exception e) { + throw new RuntimeException(e); + } + } + } + } + + private static void threadSleep() throws InterruptedException { + + Thread t1 = new Thread(ThreadExecutionQuestion::action, "t1"); + Thread t2 = new Thread(ThreadExecutionQuestion::action, "t2"); + Thread t3 = new Thread(ThreadExecutionQuestion::action, "t3"); + + t1.start(); + + while (t1.isAlive()) { + // sleep + Thread.sleep(0); + } + + t2.start(); + + while (t2.isAlive()) { + Thread.sleep(0); + } + + t3.start(); + + while (t3.isAlive()) { + Thread.sleep(0); + } + + } + + private static void threadLoop() { + + Thread t1 = new Thread(ThreadExecutionQuestion::action, "t1"); + Thread t2 = new Thread(ThreadExecutionQuestion::action, "t2"); + Thread t3 = new Thread(ThreadExecutionQuestion::action, "t3"); + + t1.start(); + + while (t1.isAlive()) { + // 自旋 Spin + } + + t2.start(); + + while (t2.isAlive()) { + + } + + t3.start(); + + while (t3.isAlive()) { + + } + + } + + private static void threadJoinOneByOne() throws InterruptedException { + Thread t1 = new Thread(ThreadExecutionQuestion::action, "t1"); + Thread t2 = new Thread(ThreadExecutionQuestion::action, "t2"); + Thread t3 = new Thread(ThreadExecutionQuestion::action, "t3"); + + // start() 仅是通知线程启动 + t1.start(); + // join() 控制线程必须执行完成 + t1.join(); + + t2.start(); + t2.join(); + + t3.start(); + t3.join(); + } + + private static void action() { + System.out.printf("线程[%s] 正在执行...\n", Thread.currentThread().getName()); // 2 + } +} diff --git "a/2019.04.12 \343\200\214\345\260\217\351\251\254\345\223\245\346\212\200\346\234\257\345\221\250\346\212\245\343\200\215- \347\254\254\344\272\214\345\215\201\344\270\211\346\234\237\343\200\212\351\235\242\350\257\225\350\231\220\346\210\221\345\215\203\347\231\276\351\201\215\357\274\214Java \345\271\266\345\217\221\347\234\237\350\256\250\345\216\214\357\274\210\347\273\255\357\274\211\343\200\213/java-concurrency/src/com/imooc/interview/questions/java/concurrency/thread/ThreadPoolExecutorExceptionQuestion.java" "b/2019.04.12 \343\200\214\345\260\217\351\251\254\345\223\245\346\212\200\346\234\257\345\221\250\346\212\245\343\200\215- \347\254\254\344\272\214\345\215\201\344\270\211\346\234\237\343\200\212\351\235\242\350\257\225\350\231\220\346\210\221\345\215\203\347\231\276\351\201\215\357\274\214Java \345\271\266\345\217\221\347\234\237\350\256\250\345\216\214\357\274\210\347\273\255\357\274\211\343\200\213/java-concurrency/src/com/imooc/interview/questions/java/concurrency/thread/ThreadPoolExecutorExceptionQuestion.java" new file mode 100644 index 0000000..f1dd543 --- /dev/null +++ "b/2019.04.12 \343\200\214\345\260\217\351\251\254\345\223\245\346\212\200\346\234\257\345\221\250\346\212\245\343\200\215- \347\254\254\344\272\214\345\215\201\344\270\211\346\234\237\343\200\212\351\235\242\350\257\225\350\231\220\346\210\221\345\215\203\347\231\276\351\201\215\357\274\214Java \345\271\266\345\217\221\347\234\237\350\256\250\345\216\214\357\274\210\347\273\255\357\274\211\343\200\213/java-concurrency/src/com/imooc/interview/questions/java/concurrency/thread/ThreadPoolExecutorExceptionQuestion.java" @@ -0,0 +1,44 @@ +package com.imooc.interview.questions.java.concurrency.thread; + +import java.util.concurrent.*; + +public class ThreadPoolExecutorExceptionQuestion { + + public static void main(String[] args) throws InterruptedException { + +// ExecutorService executorService = Executors.newFixedThreadPool(2); + + ThreadPoolExecutor executorService = new ThreadPoolExecutor( + 1, + 1, + 0, + TimeUnit.MILLISECONDS, + new LinkedBlockingQueue<>() + ) { + + /** + * 通过覆盖 {@link ThreadPoolExecutor#afterExecute(Runnable, Throwable)} 达到获取异常的信息 + * @param r + * @param t + */ + @Override + protected void afterExecute(Runnable r, Throwable t) { + System.out.printf("线程[%s] 遇到了异常,详细信息:%s\n", + Thread.currentThread().getName(), + t.getMessage()); + } + + }; + + executorService.execute(() -> { + throw new RuntimeException("数据达到阈值"); + }); + + // 等待一秒钟,确保提交的任务完成 + executorService.awaitTermination(1, TimeUnit.SECONDS); + + // 关闭线程池 + executorService.shutdown(); + + } +} diff --git "a/2019.04.12 \343\200\214\345\260\217\351\251\254\345\223\245\346\212\200\346\234\257\345\221\250\346\212\245\343\200\215- \347\254\254\344\272\214\345\215\201\344\270\211\346\234\237\343\200\212\351\235\242\350\257\225\350\231\220\346\210\221\345\215\203\347\231\276\351\201\215\357\274\214Java \345\271\266\345\217\221\347\234\237\350\256\250\345\216\214\357\274\210\347\273\255\357\274\211\343\200\213/java-concurrency/src/com/imooc/interview/questions/java/concurrency/thread/ThreadStateQuestion.java" "b/2019.04.12 \343\200\214\345\260\217\351\251\254\345\223\245\346\212\200\346\234\257\345\221\250\346\212\245\343\200\215- \347\254\254\344\272\214\345\215\201\344\270\211\346\234\237\343\200\212\351\235\242\350\257\225\350\231\220\346\210\221\345\215\203\347\231\276\351\201\215\357\274\214Java \345\271\266\345\217\221\347\234\237\350\256\250\345\216\214\357\274\210\347\273\255\357\274\211\343\200\213/java-concurrency/src/com/imooc/interview/questions/java/concurrency/thread/ThreadStateQuestion.java" new file mode 100644 index 0000000..b6a489b --- /dev/null +++ "b/2019.04.12 \343\200\214\345\260\217\351\251\254\345\223\245\346\212\200\346\234\257\345\221\250\346\212\245\343\200\215- \347\254\254\344\272\214\345\215\201\344\270\211\346\234\237\343\200\212\351\235\242\350\257\225\350\231\220\346\210\221\345\215\203\347\231\276\351\201\215\357\274\214Java \345\271\266\345\217\221\347\234\237\350\256\250\345\216\214\357\274\210\347\273\255\357\274\211\343\200\213/java-concurrency/src/com/imooc/interview/questions/java/concurrency/thread/ThreadStateQuestion.java" @@ -0,0 +1,21 @@ +package com.imooc.interview.questions.java.concurrency.thread; + +public class ThreadStateQuestion { + + + public static void main(String[] args) { + + // main 线程 -> 子线程 + Thread thread = new Thread(() -> { // new Runnable(){ public void run(){...}}; + System.out.printf("线程[%s] 正在执行...\n", Thread.currentThread().getName()); // 2 + }, "子线程-1"); + + // 启动线程 + thread.start(); + + // 先于 Runnable 执行 + System.out.printf("线程[%s] 是否还活着: %s\n", thread.getName(), thread.isAlive()); // 1 + // 在 Java 中,执行线程 Java 是没有办法销毁它的, + // 但是当 Thread.isAlive() 返回 false 时,实际底层的 Thread 已经被销毁了 + } +} diff --git "a/2019.04.12 \343\200\214\345\260\217\351\251\254\345\223\245\346\212\200\346\234\257\345\221\250\346\212\245\343\200\215- \347\254\254\344\272\214\345\215\201\344\270\211\346\234\237\343\200\212\351\235\242\350\257\225\350\231\220\346\210\221\345\215\203\347\231\276\351\201\215\357\274\214Java \345\271\266\345\217\221\347\234\237\350\256\250\345\216\214\357\274\210\347\273\255\357\274\211\343\200\213/java-concurrency/src/com/imooc/interview/questions/java/concurrency/thread/pool/ExecutorServiceQuestion.java" "b/2019.04.12 \343\200\214\345\260\217\351\251\254\345\223\245\346\212\200\346\234\257\345\221\250\346\212\245\343\200\215- \347\254\254\344\272\214\345\215\201\344\270\211\346\234\237\343\200\212\351\235\242\350\257\225\350\231\220\346\210\221\345\215\203\347\231\276\351\201\215\357\274\214Java \345\271\266\345\217\221\347\234\237\350\256\250\345\216\214\357\274\210\347\273\255\357\274\211\343\200\213/java-concurrency/src/com/imooc/interview/questions/java/concurrency/thread/pool/ExecutorServiceQuestion.java" new file mode 100644 index 0000000..f793261 --- /dev/null +++ "b/2019.04.12 \343\200\214\345\260\217\351\251\254\345\223\245\346\212\200\346\234\257\345\221\250\346\212\245\343\200\215- \347\254\254\344\272\214\345\215\201\344\270\211\346\234\237\343\200\212\351\235\242\350\257\225\350\231\220\346\210\221\345\215\203\347\231\276\351\201\215\357\274\214Java \345\271\266\345\217\221\347\234\237\350\256\250\345\216\214\357\274\210\347\273\255\357\274\211\343\200\213/java-concurrency/src/com/imooc/interview/questions/java/concurrency/thread/pool/ExecutorServiceQuestion.java" @@ -0,0 +1,23 @@ +package com.imooc.interview.questions.java.concurrency.thread.pool; + +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + +public class ExecutorServiceQuestion { + + public static void main(String[] args) { + /** + * 1.5 + * ThreadPoolExecutor + * ScheduledThreadPoolExecutor :: ThreadPoolExecutor + * 1.7 + * ForkJoinPool + */ + ExecutorService executorService = Executors.newFixedThreadPool(2); + + executorService = Executors.newScheduledThreadPool(2); + + // executorService 不再被引用,它会被 GC -> finalize() -> shutdown() + ExecutorService executorService2 = Executors.newSingleThreadExecutor(); + } +} diff --git "a/2019.04.12 \343\200\214\345\260\217\351\251\254\345\223\245\346\212\200\346\234\257\345\221\250\346\212\245\343\200\215- \347\254\254\344\272\214\345\215\201\344\270\211\346\234\237\343\200\212\351\235\242\350\257\225\350\231\220\346\210\221\345\215\203\347\231\276\351\201\215\357\274\214Java \345\271\266\345\217\221\347\234\237\350\256\250\345\216\214\357\274\210\347\273\255\357\274\211\343\200\213/java-concurrency/src/com/imooc/interview/questions/java/concurrency/thread/pool/ThreadPoolExecutorThreadQuestion.java" "b/2019.04.12 \343\200\214\345\260\217\351\251\254\345\223\245\346\212\200\346\234\257\345\221\250\346\212\245\343\200\215- \347\254\254\344\272\214\345\215\201\344\270\211\346\234\237\343\200\212\351\235\242\350\257\225\350\231\220\346\210\221\345\215\203\347\231\276\351\201\215\357\274\214Java \345\271\266\345\217\221\347\234\237\350\256\250\345\216\214\357\274\210\347\273\255\357\274\211\343\200\213/java-concurrency/src/com/imooc/interview/questions/java/concurrency/thread/pool/ThreadPoolExecutorThreadQuestion.java" new file mode 100644 index 0000000..73c87d9 --- /dev/null +++ "b/2019.04.12 \343\200\214\345\260\217\351\251\254\345\223\245\346\212\200\346\234\257\345\221\250\346\212\245\343\200\215- \347\254\254\344\272\214\345\215\201\344\270\211\346\234\237\343\200\212\351\235\242\350\257\225\350\231\220\346\210\221\345\215\203\347\231\276\351\201\215\357\274\214Java \345\271\266\345\217\221\347\234\237\350\256\250\345\216\214\357\274\210\347\273\255\357\274\211\343\200\213/java-concurrency/src/com/imooc/interview/questions/java/concurrency/thread/pool/ThreadPoolExecutorThreadQuestion.java" @@ -0,0 +1,81 @@ +package com.imooc.interview.questions.java.concurrency.thread.pool; + +import java.util.HashSet; +import java.util.Set; +import java.util.concurrent.*; +import java.util.stream.Stream; + +public class ThreadPoolExecutorThreadQuestion { + + public static void main(String[] args) throws InterruptedException { + + // main 线程启动子线程,子线程的创造来自于 Executors.defaultThreadFactory() + + ExecutorService executorService = Executors.newCachedThreadPool(); + // 之前了解 ThreadPoolExecutor beforeExecute 和 afterExecute 能够获取当前线程数量 + + Set threadsContainer = new HashSet<>(); + + setThreadFactory(executorService, threadsContainer); + for (int i = 0; i < 9; i++) { // 开启 9 个线程 + executorService.submit(() -> { + }); + } + + // 线程池等待执行 3 ms + executorService.awaitTermination(3, TimeUnit.MILLISECONDS); + + threadsContainer.stream() + .filter(Thread::isAlive) + .forEach(thread -> { + System.out.println("线程池创造的线程 : " + thread); + }); + + Thread mainThread = Thread.currentThread(); + + ThreadGroup mainThreadGroup = mainThread.getThreadGroup(); + + int count = mainThreadGroup.activeCount(); + Thread[] threads = new Thread[count]; + mainThreadGroup.enumerate(threads, true); + + Stream.of(threads) + .filter(Thread::isAlive) + .forEach(thread -> { + System.out.println("线程 : " + thread); + }); + + // 关闭线程池 + executorService.shutdown(); + + } + + private static void setThreadFactory(ExecutorService executorService, Set threadsContainer) { + + if (executorService instanceof ThreadPoolExecutor) { + ThreadPoolExecutor threadPoolExecutor = (ThreadPoolExecutor) executorService; + ThreadFactory oldThreadFactory = threadPoolExecutor.getThreadFactory(); + threadPoolExecutor.setThreadFactory(new DelegatingThreadFactory(oldThreadFactory, threadsContainer)); + } + } + + private static class DelegatingThreadFactory implements ThreadFactory { + + private final ThreadFactory delegate; + + private final Set threadsContainer; + + private DelegatingThreadFactory(ThreadFactory delegate, Set threadsContainer) { + this.delegate = delegate; + this.threadsContainer = threadsContainer; + } + + @Override + public Thread newThread(Runnable r) { + Thread thread = delegate.newThread(r); + // cache thread + threadsContainer.add(thread); + return thread; + } + } +}