diff --git "a/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\344\273\243\347\240\201/segmentfault/deep-in-java/stage-2/lesson-4/src/main/java/com/segmentfault/deep/in/java/collection/algorithm/QuickSort.java" "b/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\344\273\243\347\240\201/segmentfault/deep-in-java/stage-2/lesson-4/src/main/java/com/segmentfault/deep/in/java/collection/algorithm/QuickSort.java" index 1ce2988..8304c19 100644 --- "a/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\344\273\243\347\240\201/segmentfault/deep-in-java/stage-2/lesson-4/src/main/java/com/segmentfault/deep/in/java/collection/algorithm/QuickSort.java" +++ "b/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\344\273\243\347\240\201/segmentfault/deep-in-java/stage-2/lesson-4/src/main/java/com/segmentfault/deep/in/java/collection/algorithm/QuickSort.java" @@ -1,5 +1,6 @@ package com.segmentfault.deep.in.java.collection.algorithm; +import java.util.Arrays; import java.util.stream.Stream; public class QuickSort> implements Sort { @@ -82,9 +83,9 @@ int partition(T[] values, int low, int high) { } public static void main(String[] args) { - Integer[] values = Sort.of(3, 1, 2, 5, 4); + Integer[] values = Sort.of(2, 5, 6, 7, 8, 8, 9, 2, 1, 6, 7, 5, 6, 11, 23); Sort sort = new QuickSort<>(); // Java 7 Diamond 语法 sort.sort(values); - Stream.of(values).forEach(System.out::println); + System.out.println(Arrays.asList(values)); } } diff --git "a/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\344\273\243\347\240\201/segmentfault/deep-in-java/stage-3/pom.xml" "b/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\344\273\243\347\240\201/segmentfault/deep-in-java/stage-3/pom.xml" index 20aac00..fe88fd6 100644 --- "a/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\344\273\243\347\240\201/segmentfault/deep-in-java/stage-3/pom.xml" +++ "b/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\344\273\243\347\240\201/segmentfault/deep-in-java/stage-3/pom.xml" @@ -15,6 +15,7 @@ stage-3-lesson-1 stage-3-lesson-2 stage-3-lesson-3 + stage-3-lesson-4 pom diff --git "a/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\344\273\243\347\240\201/segmentfault/deep-in-java/stage-3/stage-3-lesson-4/pom.xml" "b/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\344\273\243\347\240\201/segmentfault/deep-in-java/stage-3/stage-3-lesson-4/pom.xml" new file mode 100644 index 0000000..f4cef6e --- /dev/null +++ "b/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\344\273\243\347\240\201/segmentfault/deep-in-java/stage-3/stage-3-lesson-4/pom.xml" @@ -0,0 +1,15 @@ + + + + stage-3 + com.segmentfault + 1.0-SNAPSHOT + + 4.0.0 + + stage-3-lesson-4 + 「一入 Java 深似海 」系列 :: 第三期 :: 第四节 + https://segmentfault.com/ls/1650000018320970/l/1500000018320681 + \ No newline at end of file diff --git "a/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\344\273\243\347\240\201/segmentfault/deep-in-java/stage-3/stage-3-lesson-4/src/main/java/com/segmentfault/deep/in/java/concurrency/ArrayBlockingQueueConcurrentDemo.java" "b/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\344\273\243\347\240\201/segmentfault/deep-in-java/stage-3/stage-3-lesson-4/src/main/java/com/segmentfault/deep/in/java/concurrency/ArrayBlockingQueueConcurrentDemo.java" new file mode 100644 index 0000000..7f04cbc --- /dev/null +++ "b/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\344\273\243\347\240\201/segmentfault/deep-in-java/stage-3/stage-3-lesson-4/src/main/java/com/segmentfault/deep/in/java/concurrency/ArrayBlockingQueueConcurrentDemo.java" @@ -0,0 +1,43 @@ +package com.segmentfault.deep.in.java.concurrency; + +import java.util.concurrent.*; +import java.util.concurrent.atomic.AtomicInteger; + +public class ArrayBlockingQueueConcurrentDemo { + + public static void main(String[] args) throws InterruptedException { + + // 最大允许添加 2 个元素 + BlockingQueue queue = new ArrayBlockingQueue<>(2, true); + // 申请 2 个大小的线程池 + ExecutorService executorService = Executors.newFixedThreadPool(2); + + for (AtomicInteger i = new AtomicInteger(1); i.get() < 100; i.incrementAndGet()) { + executorService.submit(() -> { // 写线程(1) + try { + queue.put(i.get()); + } catch (InterruptedException e) { + e.printStackTrace(); + } + }); + + executorService.submit(() -> { // 读线程(1) + try { + System.out.println(queue.take()); + } catch (InterruptedException e) { + e.printStackTrace(); + } + }); + } + +// executorService.submit(() -> { // 写线程(2) +// queue.put(2); +// }); + + + executorService.awaitTermination(10, TimeUnit.SECONDS); + // 关闭线程池 + executorService.shutdown(); + + } +} diff --git "a/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\344\273\243\347\240\201/segmentfault/deep-in-java/stage-3/stage-3-lesson-4/src/main/java/com/segmentfault/deep/in/java/concurrency/ArrayBlockingQueueDemo.java" "b/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\344\273\243\347\240\201/segmentfault/deep-in-java/stage-3/stage-3-lesson-4/src/main/java/com/segmentfault/deep/in/java/concurrency/ArrayBlockingQueueDemo.java" new file mode 100644 index 0000000..158b04d --- /dev/null +++ "b/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\344\273\243\347\240\201/segmentfault/deep-in-java/stage-3/stage-3-lesson-4/src/main/java/com/segmentfault/deep/in/java/concurrency/ArrayBlockingQueueDemo.java" @@ -0,0 +1,46 @@ +package com.segmentfault.deep.in.java.concurrency; + +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.BlockingQueue; + +public class ArrayBlockingQueueDemo { + + public static void main(String[] args) throws InterruptedException { + + // ArrayBlockingQueue 是有限队列 + ArrayBlockingQueue queue = new ArrayBlockingQueue(3); + + // Queue 添加操作中 offer 安全性高于 add 方法 +// demoOfferMethod(queue); +// demoAddMethod(queue); + + demoPutMethod(queue); + // BlockingQueue 要使用 put 方法多于 offer 方法 + + System.out.println(queue); + } + + private static void demoPutMethod(BlockingQueue queue) throws InterruptedException { + queue.put(1); + queue.put(2); + queue.put(3); + // 如果超过了 capacity,? + queue.put(4); + } + + private static void demoAddMethod(BlockingQueue queue) { + queue.add(1); + queue.add(2); + queue.add(3); + // 如果超过了 capacity,throw new IllegalStateException("Queue full") +// queue.add(4); + } + + private static void demoOfferMethod(BlockingQueue queue) { + queue.offer(1); + queue.offer(2); + queue.offer(3); + // 如果超过了 capacity,后面的offer 会被忽略 + queue.offer(4); + } +} diff --git "a/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\344\273\243\347\240\201/segmentfault/deep-in-java/stage-3/stage-3-lesson-4/src/main/java/com/segmentfault/deep/in/java/concurrency/CompletableFutureDemo.java" "b/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\344\273\243\347\240\201/segmentfault/deep-in-java/stage-3/stage-3-lesson-4/src/main/java/com/segmentfault/deep/in/java/concurrency/CompletableFutureDemo.java" new file mode 100644 index 0000000..3904c5d --- /dev/null +++ "b/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\344\273\243\347\240\201/segmentfault/deep-in-java/stage-3/stage-3-lesson-4/src/main/java/com/segmentfault/deep/in/java/concurrency/CompletableFutureDemo.java" @@ -0,0 +1,17 @@ +package com.segmentfault.deep.in.java.concurrency; + +import java.util.concurrent.CompletableFuture; + +public class CompletableFutureDemo { + + public static void main(String[] args) { + // CompletableFuture + + CompletableFuture.supplyAsync(() -> { + return 1; + }).thenApply(String::valueOf) + // 异常的方式结束 + .completeExceptionally(new RuntimeException()) + ; + } +} diff --git "a/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\344\273\243\347\240\201/segmentfault/deep-in-java/stage-3/stage-3-lesson-4/src/main/java/com/segmentfault/deep/in/java/concurrency/ConcurrentHashMapDemo.java" "b/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\344\273\243\347\240\201/segmentfault/deep-in-java/stage-3/stage-3-lesson-4/src/main/java/com/segmentfault/deep/in/java/concurrency/ConcurrentHashMapDemo.java" new file mode 100644 index 0000000..cd11224 --- /dev/null +++ "b/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\344\273\243\347\240\201/segmentfault/deep-in-java/stage-3/stage-3-lesson-4/src/main/java/com/segmentfault/deep/in/java/concurrency/ConcurrentHashMapDemo.java" @@ -0,0 +1,22 @@ +package com.segmentfault.deep.in.java.concurrency; + +public class ConcurrentHashMapDemo { + + public static void main(String[] args) { + + // ConcurrentHashMap 读多写少场景 + // 1.6 读(部分锁) -> 1.7 无锁(Segment) -> 1.8 无锁(红黑树——更好地解决 Hash 冲突) + // ConcurrentSkipListMap 读多写多场景(如果内存足够时) + + // ConcurrentHashMap + // table 2^n -> + // n = 1 -> size = 2 + // n = 2 -> size = 2^2 = 4 + // n = 3 -> size = 2^3 = 8 TREEIFY_THRESHOLD + // log2(8) = 3 + // [0] -> [1] -> [2] + // [0] -> [1] + // -> [2] + // n = 4 -> size = 2^4 = 16 + } +} diff --git "a/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\344\273\243\347\240\201/segmentfault/deep-in-java/stage-3/stage-3-lesson-4/src/main/java/com/segmentfault/deep/in/java/concurrency/CopyOnWriteArrayListDemo.java" "b/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\344\273\243\347\240\201/segmentfault/deep-in-java/stage-3/stage-3-lesson-4/src/main/java/com/segmentfault/deep/in/java/concurrency/CopyOnWriteArrayListDemo.java" new file mode 100644 index 0000000..4f00616 --- /dev/null +++ "b/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\344\273\243\347\240\201/segmentfault/deep-in-java/stage-3/stage-3-lesson-4/src/main/java/com/segmentfault/deep/in/java/concurrency/CopyOnWriteArrayListDemo.java" @@ -0,0 +1,31 @@ +package com.segmentfault.deep.in.java.concurrency; + +import java.util.Iterator; +import java.util.concurrent.CopyOnWriteArrayList; + +public class CopyOnWriteArrayListDemo { + + public static void main(String[] args) { + CopyOnWriteArrayList list = new CopyOnWriteArrayList<>(); // Diamond 语法 + + // main 线程插入三条数据 + // 安装 Thread ID + list.add(1); + // 判断当前线程 ID == main.threadId + list.add(2); + list.add(3); + // Copy + // JDK 升级两大核心性能提升 + // 1. 数组 + // 2. String + + // ConcurrentModificationException + int times = 0; + Iterator iterator = list.iterator(); + while (iterator.hasNext() && times < 100) { + iterator.next(); + list.add(2); + times++; + } + } +} diff --git "a/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\344\273\243\347\240\201/segmentfault/deep-in-java/stage-3/stage-3-lesson-4/src/main/java/com/segmentfault/deep/in/java/concurrency/HashMapDemo.java" "b/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\344\273\243\347\240\201/segmentfault/deep-in-java/stage-3/stage-3-lesson-4/src/main/java/com/segmentfault/deep/in/java/concurrency/HashMapDemo.java" new file mode 100644 index 0000000..bf748b7 --- /dev/null +++ "b/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\344\273\243\347\240\201/segmentfault/deep-in-java/stage-3/stage-3-lesson-4/src/main/java/com/segmentfault/deep/in/java/concurrency/HashMapDemo.java" @@ -0,0 +1,19 @@ +package com.segmentfault.deep.in.java.concurrency; + +import java.util.HashMap; +import java.util.Map; + +public class HashMapDemo { + + public static void main(String[] args) { + + String strValue = "Hello,World"; + + Integer intValue = new Integer(strValue.hashCode()); + + Map map = new HashMap<>(); + + map.put(strValue, 1); + map.put(intValue, 2); + } +} diff --git "a/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\344\273\243\347\240\201/segmentfault/deep-in-java/stage-3/stage-3-lesson-4/src/main/java/com/segmentfault/deep/in/java/concurrency/Java9FlowDemo.java" "b/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\344\273\243\347\240\201/segmentfault/deep-in-java/stage-3/stage-3-lesson-4/src/main/java/com/segmentfault/deep/in/java/concurrency/Java9FlowDemo.java" new file mode 100644 index 0000000..b5f9373 --- /dev/null +++ "b/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\344\273\243\347\240\201/segmentfault/deep-in-java/stage-3/stage-3-lesson-4/src/main/java/com/segmentfault/deep/in/java/concurrency/Java9FlowDemo.java" @@ -0,0 +1,72 @@ +package com.segmentfault.deep.in.java.concurrency; + +import java.util.concurrent.*; + +public class Java9FlowDemo { + + public static void main(String[] args) throws InterruptedException { + + // Java 7 try-catch 语法 + + try (SubmissionPublisher publisher = new SubmissionPublisher<>()) { + + // 订阅 + publisher.subscribe(new Flow.Subscriber() { + + private Flow.Subscription subscription; + + @Override + public void onSubscribe(Flow.Subscription subscription) { + this.subscription = subscription; + println("已订阅"); + // 订阅无限(Long.MAX_VALUE)数据 + subscription.request(Long.MAX_VALUE); + } + + @Override + public void onNext(String item) { + if ("exit".equalsIgnoreCase(item)) { + // 取消订阅 + subscription.cancel(); + return; + } else if ("exception".equalsIgnoreCase(item)) { + throw new RuntimeException("Throw an exception..."); + } + println("得到数据:" + item); + } + + @Override + public void onError(Throwable throwable) { + println("得到异常:" + throwable); + } + + @Override + public void onComplete() { + println("操作完成"); + } + }); + + // 发布者发布数据 + publisher.submit("Hello,World"); + publisher.submit("2019"); + + // 故意抛出异常 + publisher.submit("exception"); + + // exit 是退出命令 + publisher.submit("exit"); + // 当 exit 出现时,忽略后续提交 + publisher.submit("ABCDEFG"); + publisher.submit("HIGKLMN"); + + ExecutorService executor = (ExecutorService) publisher.getExecutor(); + + executor.awaitTermination(100, TimeUnit.MILLISECONDS); + + } + } + + private static void println(Object object) { + System.out.printf("[线程: %s] - %s\n", Thread.currentThread().getName(), object); + } +} diff --git "a/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\344\273\243\347\240\201/segmentfault/deep-in-java/stage-3/stage-3-lesson-4/src/main/java/com/segmentfault/deep/in/java/concurrency/LinkedBlockingQueueConcurrentDemo.java" "b/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\344\273\243\347\240\201/segmentfault/deep-in-java/stage-3/stage-3-lesson-4/src/main/java/com/segmentfault/deep/in/java/concurrency/LinkedBlockingQueueConcurrentDemo.java" new file mode 100644 index 0000000..dc284b5 --- /dev/null +++ "b/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\344\273\243\347\240\201/segmentfault/deep-in-java/stage-3/stage-3-lesson-4/src/main/java/com/segmentfault/deep/in/java/concurrency/LinkedBlockingQueueConcurrentDemo.java" @@ -0,0 +1,43 @@ +package com.segmentfault.deep.in.java.concurrency; + +import java.util.concurrent.*; +import java.util.concurrent.atomic.AtomicInteger; + +public class LinkedBlockingQueueConcurrentDemo { + + public static void main(String[] args) throws InterruptedException { + + // 最大允许添加 2 个元素 + BlockingQueue queue = new LinkedBlockingQueue<>(2); + // 申请 2 个大小的线程池 + ExecutorService executorService = Executors.newFixedThreadPool(2); + + for (AtomicInteger i = new AtomicInteger(1); i.get() < 100; i.incrementAndGet()) { + executorService.submit(() -> { // 写线程(1) + try { + queue.put(i.get()); + } catch (InterruptedException e) { + e.printStackTrace(); + } + }); + + executorService.submit(() -> { // 读线程(1) + try { + System.out.println(queue.take()); + } catch (InterruptedException e) { + e.printStackTrace(); + } + }); + } + +// executorService.submit(() -> { // 写线程(2) +// queue.put(2); +// }); + + + executorService.awaitTermination(10, TimeUnit.SECONDS); + // 关闭线程池 + executorService.shutdown(); + + } +} diff --git "a/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\344\273\243\347\240\201/segmentfault/deep-in-java/stage-3/stage-3-lesson-4/src/main/java/com/segmentfault/deep/in/java/concurrency/MapEntryDemo.java" "b/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\344\273\243\347\240\201/segmentfault/deep-in-java/stage-3/stage-3-lesson-4/src/main/java/com/segmentfault/deep/in/java/concurrency/MapEntryDemo.java" new file mode 100644 index 0000000..cac5f24 --- /dev/null +++ "b/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\344\273\243\347\240\201/segmentfault/deep-in-java/stage-3/stage-3-lesson-4/src/main/java/com/segmentfault/deep/in/java/concurrency/MapEntryDemo.java" @@ -0,0 +1,51 @@ +package com.segmentfault.deep.in.java.concurrency; + +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.ConcurrentSkipListMap; + +public class MapEntryDemo { + + public static void main(String[] args) { + Map map = new HashMap<>(); + map.put("A", 1); + map.put("B", 2); + map.put("C", 3); + demoMap(map); + + System.out.println(map); + + //注意:Java Concurrent Map 可能未实现 Map.Entry#setValue(Object) 方法 + Map skipListMap = new ConcurrentSkipListMap<>(); + + skipListMap.put("A", 1); + skipListMap.put("B", 2); + skipListMap.put("C", 3); + + demoMap(skipListMap); + + System.out.println(skipListMap); + } + + private static void demoMap(Map map) { + + // 问题:如何让所有的成员值 +1 + for (Map.Entry entry : map.entrySet()) { + slowApproach(entry, map); + fastApproach(entry); + } + } + + private static void fastApproach(Map.Entry entry) { + entry.setValue(entry.getValue() + 1); + } + + private static void slowApproach(Map.Entry entry, Map map) { + String key = entry.getKey(); + Integer value = entry.getValue(); + // Key 的计算消耗时间 + // +1 + value += 1; + map.put(key, value); + } +} diff --git "a/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\344\273\243\347\240\201/segmentfault/deep-in-java/stage-3/stage-3-lesson-4/src/main/java/com/segmentfault/deep/in/java/concurrency/QuickSortForkJoinDemo.java" "b/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\344\273\243\347\240\201/segmentfault/deep-in-java/stage-3/stage-3-lesson-4/src/main/java/com/segmentfault/deep/in/java/concurrency/QuickSortForkJoinDemo.java" new file mode 100644 index 0000000..5f9a124 --- /dev/null +++ "b/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\344\273\243\347\240\201/segmentfault/deep-in-java/stage-3/stage-3-lesson-4/src/main/java/com/segmentfault/deep/in/java/concurrency/QuickSortForkJoinDemo.java" @@ -0,0 +1,104 @@ +package com.segmentfault.deep.in.java.concurrency; + +import java.util.Arrays; +import java.util.concurrent.ForkJoinPool; +import java.util.concurrent.RecursiveAction; +import java.util.concurrent.TimeUnit; + +public class QuickSortForkJoinDemo { + + public static void main(String[] args) throws InterruptedException { + + Integer[] values = new Integer[]{2, 5, 6, 7, 8, 8, 9, 2, 1, 6, 7, 5, 6, 11, 23}; + + ForkJoinPool pool = new ForkJoinPool(); + + pool.submit(new QuickSortTask(values)); + + pool.awaitTermination(100, TimeUnit.MILLISECONDS); + + pool.shutdown(); + + System.out.println(Arrays.asList(values)); + } + + private static class QuickSortTask extends RecursiveAction { + + private final Integer[] parts; + + private final int low; + + private final int high; + // 设置一个阈值 + private static final int THRESHOLD = 4; + + private QuickSortTask(Integer[] parts) { + this.parts = parts; + this.low = 0; + this.high = parts.length - 1; + } + + private QuickSortTask(Integer[] parts, int low, int high) { + this.parts = parts; + this.low = low; + this.high = high; + } + + @Override + protected void compute() { + if (high - low < THRESHOLD) { // 范围低于阈值时,直接排序 + sort(parts, low, high); + } else { + int pivot = partition(parts, low, high); + QuickSortTask task = new QuickSortTask(parts, low, pivot - 1); + QuickSortTask task2 = new QuickSortTask(parts, pivot + 1, high); + task.fork().join(); + task2.fork().join(); + } + } + + /** + * 获取分区索引 + * + * @param values 数组对象 + * @param low 低位索引 + * @param high 高位索引 + * @return 分区索引 + */ + int partition(Integer[] values, int low, int high) { + // 获取 pivot = values[high] + + // [3, 1, 2, 5, 4] + // pivot = 4 + // -1 + // [0] = 3 < 4 (0) + // [1] = 1 < 4 (1) + // [2] = 2 < 4 (2) + // [3] = 5 > 4 (3) + // => [(3, 1, 2), (4), (5)] + // pIndex = 3 + + Integer pivot = values[high]; + int i = low; + + for (int j = low; j < high; j++) { + if (values[j].compareTo(pivot) < 1) { // <= + Integer temp = values[i]; // 低位数据 + values[i] = values[j]; // 低位数据获取高位数据 + values[j] = temp; + i++; // -1 -> 0 + } + } + + Integer temp = values[i]; + values[i] = values[high]; + values[high] = temp; + + return i; + } + + private void sort(Integer[] parts, int low, int high) { + Arrays.sort(parts, low, high + 1); + } + } +} diff --git "a/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\344\273\243\347\240\201/segmentfault/deep-in-java/stage-3/stage-3-lesson-4/src/main/java/com/segmentfault/deep/in/java/concurrency/SynchronousQueueDemo.java" "b/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\344\273\243\347\240\201/segmentfault/deep-in-java/stage-3/stage-3-lesson-4/src/main/java/com/segmentfault/deep/in/java/concurrency/SynchronousQueueDemo.java" new file mode 100644 index 0000000..1728c3b --- /dev/null +++ "b/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\344\273\243\347\240\201/segmentfault/deep-in-java/stage-3/stage-3-lesson-4/src/main/java/com/segmentfault/deep/in/java/concurrency/SynchronousQueueDemo.java" @@ -0,0 +1,72 @@ +package com.segmentfault.deep.in.java.concurrency; + +import java.util.concurrent.*; +import java.util.concurrent.atomic.AtomicInteger; + +public class SynchronousQueueDemo { + + public static void main(String[] args) throws InterruptedException { + + + // SynchronousQueue 互斥使用场景 + // SynchronousQueue put() 完成之后,必须被其他线程 take() + // capacity == 0 , 又允许插入(put) 一个元素 + // offer 方法无效,add 方法抛出异常 + BlockingQueue sQueue = new SynchronousQueue<>(true); + // 申请 2 个大小的线程池 + ExecutorService executorService = Executors.newFixedThreadPool(2); + + for (AtomicInteger i = new AtomicInteger(1); i.get() < 100; i.incrementAndGet()) { + executorService.execute(() -> { // 写线程 + try { + // 必须要有 put,不能用 offer + // BlockingQueue 尽可能用 put,避免使用 offer,最好不要用 add + // sQueue.offer(1); // 如果 SynchronousQueue 被其他线程调用 take() 方法的话,会发生死锁 + sQueue.put(i.get()); + } catch (Exception e) { + e.printStackTrace(); + } + }); + + executorService.execute(() -> { // 读线程 + try { + System.out.println(sQueue.take()); + } catch (InterruptedException e) { + e.printStackTrace(); + } + }); + } + + executorService.awaitTermination(10, TimeUnit.MICROSECONDS); + + executorService.shutdown(); + } + + private static void synchronousQueuevsArrayBlockingQueue() throws InterruptedException { + // size == 0 特殊 ArrayBlockingQueue + BlockingQueue sQueue = new SynchronousQueue(); + sQueue.put(1); + + System.out.println(sQueue.size()); + + BlockingQueue aQueue = new ArrayBlockingQueue<>(1); + + aQueue.add(1); + + System.out.println(aQueue.size()); + + } + + // offer 方法来自于 Queue 接口,因此,子接口无法超越 Queue 方法签名 + + public boolean equals(Object object) +// throws Exception // 错误(编译时):超越父类 Object equals(Object) 方法签名 + throws RuntimeException // 非 checked 异常时没有以上限制 + { + + return false; + } +} + + + diff --git "a/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\347\254\254\344\270\211\346\234\237/\347\254\254\345\233\233\350\212\202 Java \345\271\266\345\217\221\346\241\206\346\236\266\351\253\230\347\272\247\350\277\220\347\224\250/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215\347\263\273\345\210\227 \347\254\254\344\270\211\346\234\237 \347\254\254\345\233\233\350\212\202 \343\200\212Java \345\271\266\345\217\221\346\241\206\346\236\266\351\253\230\347\272\247\350\277\220\347\224\250\343\200\213.pdf" "b/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\347\254\254\344\270\211\346\234\237/\347\254\254\345\233\233\350\212\202 Java \345\271\266\345\217\221\346\241\206\346\236\266\351\253\230\347\272\247\350\277\220\347\224\250/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215\347\263\273\345\210\227 \347\254\254\344\270\211\346\234\237 \347\254\254\345\233\233\350\212\202 \343\200\212Java \345\271\266\345\217\221\346\241\206\346\236\266\351\253\230\347\272\247\350\277\220\347\224\250\343\200\213.pdf" new file mode 100644 index 0000000..502c3d6 Binary files /dev/null and "b/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215/\347\254\254\344\270\211\346\234\237/\347\254\254\345\233\233\350\212\202 Java \345\271\266\345\217\221\346\241\206\346\236\266\351\253\230\347\272\247\350\277\220\347\224\250/\343\200\214\344\270\200\345\205\245 Java \346\267\261\344\274\274\346\265\267 \343\200\215\347\263\273\345\210\227 \347\254\254\344\270\211\346\234\237 \347\254\254\345\233\233\350\212\202 \343\200\212Java \345\271\266\345\217\221\346\241\206\346\236\266\351\253\230\347\272\247\350\277\220\347\224\250\343\200\213.pdf" differ