From 993446f5623d397ee9bb77f1f59994d03b6cc594 Mon Sep 17 00:00:00 2001 From: liuyiquan Date: Wed, 11 Nov 2020 20:09:40 +0800 Subject: [PATCH 1/2] =?UTF-8?q?=E6=B3=A8=E9=87=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 03concurrency/0301/pom.xml | 12 +++++++++ .../java/java0/conc0301/DaemonThread.java | 1 + .../src/main/java/java0/conc0301/Runner2.java | 5 +++- .../main/java/java0/conc0301/RunnerMain.java | 2 +- .../src/main/java/java0/conc0301/ThreadB.java | 1 + .../src/main/java/java0/conc0301/op/Join.java | 9 +++---- .../java/java0/conc0301/sync/Counter.java | 27 +++++++++++-------- .../main/java/java0/conc0301/sync/Cref.java | 1 + .../java0/conc0302/atomic/AtomicMain.java | 1 + .../java0/conc0302/lock/LockSupportDemo.java | 4 +++ .../conc0303/collection/TreeMapDemo.java | 2 +- .../future/CompletableFutureDemo.java | 7 ++--- .../conc0303/tool/CyclicBarrierDemo.java | 4 ++- 13 files changed, 53 insertions(+), 23 deletions(-) diff --git a/03concurrency/0301/pom.xml b/03concurrency/0301/pom.xml index 55691a2d..a1e16415 100644 --- a/03concurrency/0301/pom.xml +++ b/03concurrency/0301/pom.xml @@ -19,6 +19,18 @@ + + + com.google.guava + guava + 28.2-jre + + + com.ea.async + ea-async + 1.2.3 + + \ No newline at end of file diff --git a/03concurrency/0301/src/main/java/java0/conc0301/DaemonThread.java b/03concurrency/0301/src/main/java/java0/conc0301/DaemonThread.java index 5a00ab24..76d78cd3 100644 --- a/03concurrency/0301/src/main/java/java0/conc0301/DaemonThread.java +++ b/03concurrency/0301/src/main/java/java0/conc0301/DaemonThread.java @@ -17,6 +17,7 @@ public void run() { }; Thread thread = new Thread(task); thread.setName("test-thread-1"); + // 如果只有一个线程,还设置为守护线程,那么里面的逻辑不会执行 thread.setDaemon(false); thread.start(); } diff --git a/03concurrency/0301/src/main/java/java0/conc0301/Runner2.java b/03concurrency/0301/src/main/java/java0/conc0301/Runner2.java index d80e8c14..2ddcbed0 100644 --- a/03concurrency/0301/src/main/java/java0/conc0301/Runner2.java +++ b/03concurrency/0301/src/main/java/java0/conc0301/Runner2.java @@ -11,7 +11,10 @@ public void run() { boolean result = Thread.currentThread().isInterrupted(); boolean result1 = Thread.interrupted(); // 重置状态 - + /** + * 内部用一个flag变量,循环判断这个变量的值判断是否被打断 + * 每一次while都判断太浪费资源,所以每n次(比如10000轮)判断一次变量的值 + */ boolean result3 = Thread.currentThread().isInterrupted(); System.out.println("Runner2.run result ===>" + result); diff --git a/03concurrency/0301/src/main/java/java0/conc0301/RunnerMain.java b/03concurrency/0301/src/main/java/java0/conc0301/RunnerMain.java index 626f2d38..2a4f2b67 100644 --- a/03concurrency/0301/src/main/java/java0/conc0301/RunnerMain.java +++ b/03concurrency/0301/src/main/java/java0/conc0301/RunnerMain.java @@ -19,7 +19,7 @@ public static void main(String[] args) throws IOException { thread2.interrupt(); // i = true System.out.println(Thread.activeCount()); - + // 啥都不干也有两个线程,有个等待ctrl+c的线程 Thread.currentThread().getThreadGroup().list(); System.out.println(Thread.currentThread().getThreadGroup().getParent().activeGroupCount()); Thread.currentThread().getThreadGroup().getParent().list(); diff --git a/03concurrency/0301/src/main/java/java0/conc0301/ThreadB.java b/03concurrency/0301/src/main/java/java0/conc0301/ThreadB.java index fe7dda58..954458dd 100644 --- a/03concurrency/0301/src/main/java/java0/conc0301/ThreadB.java +++ b/03concurrency/0301/src/main/java/java0/conc0301/ThreadB.java @@ -15,6 +15,7 @@ public void run() { String currentThreadName = currentThread.getName(); System.out.println("这是线程的名称:" + currentThreadName); + // 活动线程为什么等于4?线程是分组的, System.out.println("返回当前线程" + currentThreadName + "的线程组中活动线程的数量:" + Thread.currentThread().getThreadGroup().activeCount()); System.out.println("返回该线程" + currentThreadName + "的标识符:" + currentThread.getId()); System.out.println("返回该线程" + currentThreadName + "的优先级:" + currentThread.getPriority()); diff --git a/03concurrency/0301/src/main/java/java0/conc0301/op/Join.java b/03concurrency/0301/src/main/java/java0/conc0301/op/Join.java index 5e60163a..13de7e28 100644 --- a/03concurrency/0301/src/main/java/java0/conc0301/op/Join.java +++ b/03concurrency/0301/src/main/java/java0/conc0301/op/Join.java @@ -8,12 +8,11 @@ public static void main(String[] args) { MyThread thread1 = new MyThread("thread1 -- "); thread1.setOo(oo); thread1.start(); - - synchronized (thread1) { + synchronized (thread1) { // 如果这里是oo for (int i = 0; i < 100; i++) { if (i == 20) { try { - thread1.join(); + thread1.join(); // join释放锁的方式 } catch (InterruptedException e) { e.printStackTrace(); } @@ -26,7 +25,7 @@ public static void main(String[] args) { } class MyThread extends Thread { - + private String name; private Object oo; @@ -40,7 +39,7 @@ public MyThread(String name) { @Override public void run() { - synchronized (this) { + synchronized (this) { // 如果这里也是oo,会卡在main -- 19。说明join没有释放锁 for (int i = 0; i < 100; i++) { System.out.println(name + i); } diff --git a/03concurrency/0301/src/main/java/java0/conc0301/sync/Counter.java b/03concurrency/0301/src/main/java/java0/conc0301/sync/Counter.java index e60845a6..3760bdd3 100644 --- a/03concurrency/0301/src/main/java/java0/conc0301/sync/Counter.java +++ b/03concurrency/0301/src/main/java/java0/conc0301/sync/Counter.java @@ -1,29 +1,31 @@ package java0.conc0301.sync; public class Counter { - - public final static int A=10; - - public static int B=10; - + + public final static int A = 10; + + public static int B = 10; + private volatile int sum = 0; + public synchronized void incr() { - sum=sum+1; + sum = sum + 1; } + public int getSum() { return sum; } - + public static void main(String[] args) throws InterruptedException { int loop = 100000; - + // test single thread Counter counter = new Counter(); for (int i = 0; i < loop; i++) { counter.incr(); } System.out.println("single thread: " + counter.getSum()); - + // test multiple threads final Counter counter2 = new Counter(); Thread t1 = new Thread(() -> { @@ -39,11 +41,14 @@ public static void main(String[] args) throws InterruptedException { t1.start(); t2.start(); Thread.sleep(1000); + /** + * yield唯一有用的地方,判断多个线程都干完活了 + */ // while (Thread.activeCount()>2){//当前线程的线程组中的数量>2 // Thread.yield(); // } System.out.println("multiple threads: " + counter2.getSum()); - - + + } } diff --git a/03concurrency/0301/src/main/java/java0/conc0301/sync/Cref.java b/03concurrency/0301/src/main/java/java0/conc0301/sync/Cref.java index f80742b0..b5ec8c16 100644 --- a/03concurrency/0301/src/main/java/java0/conc0301/sync/Cref.java +++ b/03concurrency/0301/src/main/java/java0/conc0301/sync/Cref.java @@ -2,6 +2,7 @@ public class Cref { public static void main(String[] args) { + // 反编译,常量和变量不同,常量线程安全 int x = 10; int y = Counter.B; } diff --git a/03concurrency/0301/src/main/java/java0/conc0302/atomic/AtomicMain.java b/03concurrency/0301/src/main/java/java0/conc0302/atomic/AtomicMain.java index de251e57..bf253ea5 100644 --- a/03concurrency/0301/src/main/java/java0/conc0302/atomic/AtomicMain.java +++ b/03concurrency/0301/src/main/java/java0/conc0302/atomic/AtomicMain.java @@ -4,6 +4,7 @@ public class AtomicMain { public static void main(String[] args) { + // 切换这个地方的对象 final AtomicCount count = new AtomicCount(); for (int i = 0; i < 100; i++) { new Thread(new Runnable() { diff --git a/03concurrency/0301/src/main/java/java0/conc0302/lock/LockSupportDemo.java b/03concurrency/0301/src/main/java/java0/conc0302/lock/LockSupportDemo.java index 18f598f1..f9e5913e 100644 --- a/03concurrency/0301/src/main/java/java0/conc0302/lock/LockSupportDemo.java +++ b/03concurrency/0301/src/main/java/java0/conc0302/lock/LockSupportDemo.java @@ -2,6 +2,9 @@ import java.util.concurrent.locks.LockSupport; +/** + * spring大量使用LockSupport + */ public class LockSupportDemo { public static Object u = new Object(); @@ -30,6 +33,7 @@ public static void main(String[] args) throws InterruptedException { t2.start(); Thread.sleep(3000L); t1.interrupt(); + // 为什么unpack需要一个线程做参数,因为线程没法自己唤醒自己,只能靠别人叫醒 LockSupport.unpark(t2); t1.join(); t2.join(); diff --git a/03concurrency/0301/src/main/java/java0/conc0303/collection/TreeMapDemo.java b/03concurrency/0301/src/main/java/java0/conc0303/collection/TreeMapDemo.java index bb04f20e..0c38d13f 100644 --- a/03concurrency/0301/src/main/java/java0/conc0303/collection/TreeMapDemo.java +++ b/03concurrency/0301/src/main/java/java0/conc0303/collection/TreeMapDemo.java @@ -7,7 +7,7 @@ public class TreeMapDemo { public static void main(String[] args) { - // + // 输入无序,输出有序 TreeMap map = new TreeMap<>(Comparator.reverseOrder()); map.put(3, "val"); map.put(2, "val"); diff --git a/03concurrency/0301/src/main/java/java0/conc0303/future/CompletableFutureDemo.java b/03concurrency/0301/src/main/java/java0/conc0303/future/CompletableFutureDemo.java index 2a21f4f5..d54e8da6 100644 --- a/03concurrency/0301/src/main/java/java0/conc0303/future/CompletableFutureDemo.java +++ b/03concurrency/0301/src/main/java/java0/conc0303/future/CompletableFutureDemo.java @@ -32,9 +32,10 @@ public static void main(String[] args){ return "world"; }),(s1,s2)->{return s1 + " " + s2;}).join(); System.out.println("thenCombine:"+result3); - + CompletableFuture.supplyAsync(() -> "Hello, java course.") - .thenApply(String::toUpperCase).thenCompose(s -> CompletableFuture.supplyAsync(s::toLowerCase)).thenAccept(v -> { System.out.println("thenCompose:"+v);}); + .thenApply(String::toUpperCase).thenCompose(s -> CompletableFuture.supplyAsync(s::toLowerCase)) + .thenAccept(v -> { System.out.println("thenCompose:"+v);}); // 4.竞争 System.out.println("=====>4.竞争"); @@ -68,7 +69,7 @@ public static void main(String[] args){ } return "Hi Boy"; - }).exceptionally(e->{ + }).exceptionally(e->{ // Fluent API System.out.println(e.getMessage()); return "Hello world!"; }).join(); diff --git a/03concurrency/0301/src/main/java/java0/conc0303/tool/CyclicBarrierDemo.java b/03concurrency/0301/src/main/java/java0/conc0303/tool/CyclicBarrierDemo.java index bc8417d7..dcc6c8a6 100644 --- a/03concurrency/0301/src/main/java/java0/conc0303/tool/CyclicBarrierDemo.java +++ b/03concurrency/0301/src/main/java/java0/conc0303/tool/CyclicBarrierDemo.java @@ -9,13 +9,15 @@ public static void main(String[] args) throws InterruptedException { public void run() { System.out.println("回调>>"+Thread.currentThread().getName()); System.out.println("回调>>线程组执行结束"); + System.out.println("==>各个子线程【真的】执行结束。。。。"); + } }); for (int i = 0; i < 5; i++) { new Thread(new readNum(i,cyclicBarrier)).start(); } - System.out.println("==>各个子线程执行结束。。。。"); + System.out.println("==>各个子线程【假的】执行结束。。。。"); System.out.println("==>主线程执行结束。。。。"); //CyclicBarrier 可以重复利用, From 02585edcd586b23e30dfaa4cf6163dc051dca18f Mon Sep 17 00:00:00 2001 From: liuyiquan Date: Thu, 12 Nov 2020 21:23:50 +0800 Subject: [PATCH 2/2] =?UTF-8?q?=E6=B3=A8=E9=87=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java0/conc0303/collection/CopyOnWriteArrayListDemo2.java | 4 ++-- .../main/java/java0/conc0303/threadlocal/ThreadLocalDemo.java | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/03concurrency/0301/src/main/java/java0/conc0303/collection/CopyOnWriteArrayListDemo2.java b/03concurrency/0301/src/main/java/java0/conc0303/collection/CopyOnWriteArrayListDemo2.java index 94ae2427..29e310fe 100644 --- a/03concurrency/0301/src/main/java/java0/conc0303/collection/CopyOnWriteArrayListDemo2.java +++ b/03concurrency/0301/src/main/java/java0/conc0303/collection/CopyOnWriteArrayListDemo2.java @@ -3,7 +3,7 @@ import java.util.concurrent.CopyOnWriteArrayList; public class CopyOnWriteArrayListDemo2 { - + // 并不能证明线程不安全 private final static CopyOnWriteArrayList list = new CopyOnWriteArrayList(); public static void main(String[] args) { @@ -22,7 +22,7 @@ public static void test(){ @Override public void run() { while (true) { - if (list.size() > 0) { // todo : 下一个get操作执行时,size可能已经是0了 + if (list.size() > 0) { // 下一个get操作执行时,size可能已经是0了 String content = list.get(list.size() - 1); }else { break; diff --git a/03concurrency/0301/src/main/java/java0/conc0303/threadlocal/ThreadLocalDemo.java b/03concurrency/0301/src/main/java/java0/conc0303/threadlocal/ThreadLocalDemo.java index bbfe35e0..bfe857f7 100644 --- a/03concurrency/0301/src/main/java/java0/conc0303/threadlocal/ThreadLocalDemo.java +++ b/03concurrency/0301/src/main/java/java0/conc0303/threadlocal/ThreadLocalDemo.java @@ -1,5 +1,6 @@ package java0.conc0303.threadlocal; +// 框架使用,隐式传参,多个方法之间不用一直传 public class ThreadLocalDemo { private static ThreadLocal seqNum = new ThreadLocal() {