From 518a399355f4bffb5761ade979c49a1b93ce9017 Mon Sep 17 00:00:00 2001 From: Zerroi Date: Fri, 19 Apr 2024 16:04:28 +0800 Subject: [PATCH] concurrent_study --- .gitignore | 38 ++ .idea/.gitignore | 8 + .idea/encodings.xml | 8 + .idea/leetcode/editor.xml | 42 ++ .idea/leetcode/statistics.xml | 20 + .idea/misc.xml | 14 + .idea/uiDesigner.xml | 124 ++++++ .idea/vcs.xml | 6 + pom.xml | 36 ++ .../java/com/zerroi/alternateprint/Test1.java | 35 ++ .../java/com/zerroi/alternateprint/Test2.java | 44 +++ .../java/com/zerroi/alternateprint/Test3.java | 24 ++ .../java/com/zerroi/alternateprint/Test4.java | 49 +++ .../java/com/zerroi/alternateprint/Test5.java | 60 +++ .../java/com/zerroi/alternateprint/Test6.java | 50 +++ .../java/com/zerroi/charpter05/Test1.java | 18 + .../java/com/zerroi/charpter06/LockCas.java | 50 +++ .../java/com/zerroi/charpter06/Test0.java | 90 +++++ .../java/com/zerroi/charpter06/Test1.java | 29 ++ .../java/com/zerroi/charpter06/Test2.java | 69 ++++ .../java/com/zerroi/charpter06/Test3.java | 16 + .../java/com/zerroi/charpter06/Test4.java | 37 ++ .../java/com/zerroi/charpter06/Test5.java | 48 +++ .../java/com/zerroi/charpter06/Test6.java | 24 ++ .../java/com/zerroi/charpter06/Test7.java | 50 +++ .../java/com/zerroi/charpter06/Test8.java | 51 +++ .../com/zerroi/charpter06/TestUnSafe.java | 30 ++ .../com/zerroi/charpter06/UnsafeAccessor.java | 23 ++ .../java/com/zerroi/charpter07/Test1.java | 35 ++ .../java/com/zerroi/charpter07/Test2.java | 367 ++++++++++++++++++ .../java/com/zerroi/charpter08/TestAQS.java | 74 ++++ .../charpter08/TestConcurrentHashMap.java | 75 ++++ .../com/zerroi/charpter08/TestForkJoin.java | 29 ++ .../java/com/zerroi/charpter08/TestPool.java | 192 +++++++++ .../zerroi/charpter08/TestReadWriteLock.java | 64 +++ .../com/zerroi/charpter08/TestSchedule.java | 29 ++ .../com/zerroi/charpter08/TestShutdown.java | 50 +++ .../com/zerroi/charpter08/TestSubmit.java | 71 ++++ .../charpter08/TestThreadPoolExecutor.java | 25 ++ .../java/com/zerroi/charpter08/TestTimer.java | 61 +++ .../com/zerroi/pattern/RunSequentially.java | 34 ++ .../com/zerroi/pattern/RunSequentially2.java | 17 + .../com/zerroi/pattern/RunSequentially3.java | 71 ++++ .../com/zerroi/pattern/RunSequentially4.java | 65 ++++ .../com/zerroi/pattern/RunSequentially5.java | 43 ++ src/main/java/com/zerroi/pattern/Test.java | 11 + .../com/zerroi/pattern/TestStarvation.java | 50 +++ .../java/com/zerroi/test/OverallPlanning.java | 49 +++ .../com/zerroi/test/PhilosopherDinning.java | 66 ++++ .../com/zerroi/test/PhilosopherDinning2.java | 76 ++++ .../com/zerroi/test/ReentrantLockTest.java | 39 ++ .../com/zerroi/test/ReentrantLockTest2.java | 41 ++ .../com/zerroi/test/ReentrantLockTest3.java | 38 ++ .../com/zerroi/test/ReentrantLockTest4.java | 31 ++ src/main/java/com/zerroi/test/Test12.java | 24 ++ src/main/java/com/zerroi/test/Test13.java | 28 ++ src/main/java/com/zerroi/test/Test14.java | 100 +++++ src/main/java/com/zerroi/test/Test15.java | 103 +++++ src/main/java/com/zerroi/test/Test16.java | 43 ++ src/main/java/com/zerroi/test/Test17.java | 46 +++ src/main/java/com/zerroi/test/Test4.java | 18 + src/main/java/com/zerroi/test/Test5.java | 17 + src/main/java/com/zerroi/test/Test6.java | 22 ++ src/main/java/com/zerroi/test/Test7.java | 28 ++ src/main/java/com/zerroi/test/Test8.java | 31 ++ src/main/java/com/zerroi/test/Test9.java | 26 ++ src/main/java/com/zerroi/test/TestBiased.java | 28 ++ .../java/com/zerroi/test/TestBiased2.java | 46 +++ .../java/com/zerroi/test/TestBiased3.java | 45 +++ src/main/java/com/zerroi/test/TestFrames.java | 26 ++ src/main/java/com/zerroi/test/TestJoin.java | 41 ++ .../com/zerroi/test/TestWaitAndNotify.java | 10 + .../java/com/zerroi/test/TestWaitNotify.java | 39 ++ .../java/com/zerroi/test/TwoPhaseCommit.java | 43 ++ src/main/java/com/zerroi/test/test3.java | 20 + src/main/resources/logback.xml | 36 ++ tmp/1.txt | 200 ++++++++++ tmp/10.txt | 200 ++++++++++ tmp/11.txt | 200 ++++++++++ tmp/12.txt | 200 ++++++++++ tmp/13.txt | 200 ++++++++++ tmp/14.txt | 200 ++++++++++ tmp/15.txt | 200 ++++++++++ tmp/16.txt | 200 ++++++++++ tmp/17.txt | 200 ++++++++++ tmp/18.txt | 200 ++++++++++ tmp/19.txt | 200 ++++++++++ tmp/2.txt | 200 ++++++++++ tmp/20.txt | 200 ++++++++++ tmp/21.txt | 200 ++++++++++ tmp/22.txt | 200 ++++++++++ tmp/23.txt | 200 ++++++++++ tmp/24.txt | 200 ++++++++++ tmp/25.txt | 200 ++++++++++ tmp/26.txt | 200 ++++++++++ tmp/3.txt | 200 ++++++++++ tmp/4.txt | 200 ++++++++++ tmp/5.txt | 200 ++++++++++ tmp/6.txt | 200 ++++++++++ tmp/7.txt | 200 ++++++++++ tmp/8.txt | 200 ++++++++++ tmp/9.txt | 200 ++++++++++ 102 files changed, 8816 insertions(+) create mode 100644 .gitignore create mode 100644 .idea/.gitignore create mode 100644 .idea/encodings.xml create mode 100644 .idea/leetcode/editor.xml create mode 100644 .idea/leetcode/statistics.xml create mode 100644 .idea/misc.xml create mode 100644 .idea/uiDesigner.xml create mode 100644 .idea/vcs.xml create mode 100644 pom.xml create mode 100644 src/main/java/com/zerroi/alternateprint/Test1.java create mode 100644 src/main/java/com/zerroi/alternateprint/Test2.java create mode 100644 src/main/java/com/zerroi/alternateprint/Test3.java create mode 100644 src/main/java/com/zerroi/alternateprint/Test4.java create mode 100644 src/main/java/com/zerroi/alternateprint/Test5.java create mode 100644 src/main/java/com/zerroi/alternateprint/Test6.java create mode 100644 src/main/java/com/zerroi/charpter05/Test1.java create mode 100644 src/main/java/com/zerroi/charpter06/LockCas.java create mode 100644 src/main/java/com/zerroi/charpter06/Test0.java create mode 100644 src/main/java/com/zerroi/charpter06/Test1.java create mode 100644 src/main/java/com/zerroi/charpter06/Test2.java create mode 100644 src/main/java/com/zerroi/charpter06/Test3.java create mode 100644 src/main/java/com/zerroi/charpter06/Test4.java create mode 100644 src/main/java/com/zerroi/charpter06/Test5.java create mode 100644 src/main/java/com/zerroi/charpter06/Test6.java create mode 100644 src/main/java/com/zerroi/charpter06/Test7.java create mode 100644 src/main/java/com/zerroi/charpter06/Test8.java create mode 100644 src/main/java/com/zerroi/charpter06/TestUnSafe.java create mode 100644 src/main/java/com/zerroi/charpter06/UnsafeAccessor.java create mode 100644 src/main/java/com/zerroi/charpter07/Test1.java create mode 100644 src/main/java/com/zerroi/charpter07/Test2.java create mode 100644 src/main/java/com/zerroi/charpter08/TestAQS.java create mode 100644 src/main/java/com/zerroi/charpter08/TestConcurrentHashMap.java create mode 100644 src/main/java/com/zerroi/charpter08/TestForkJoin.java create mode 100644 src/main/java/com/zerroi/charpter08/TestPool.java create mode 100644 src/main/java/com/zerroi/charpter08/TestReadWriteLock.java create mode 100644 src/main/java/com/zerroi/charpter08/TestSchedule.java create mode 100644 src/main/java/com/zerroi/charpter08/TestShutdown.java create mode 100644 src/main/java/com/zerroi/charpter08/TestSubmit.java create mode 100644 src/main/java/com/zerroi/charpter08/TestThreadPoolExecutor.java create mode 100644 src/main/java/com/zerroi/charpter08/TestTimer.java create mode 100644 src/main/java/com/zerroi/pattern/RunSequentially.java create mode 100644 src/main/java/com/zerroi/pattern/RunSequentially2.java create mode 100644 src/main/java/com/zerroi/pattern/RunSequentially3.java create mode 100644 src/main/java/com/zerroi/pattern/RunSequentially4.java create mode 100644 src/main/java/com/zerroi/pattern/RunSequentially5.java create mode 100644 src/main/java/com/zerroi/pattern/Test.java create mode 100644 src/main/java/com/zerroi/pattern/TestStarvation.java create mode 100644 src/main/java/com/zerroi/test/OverallPlanning.java create mode 100644 src/main/java/com/zerroi/test/PhilosopherDinning.java create mode 100644 src/main/java/com/zerroi/test/PhilosopherDinning2.java create mode 100644 src/main/java/com/zerroi/test/ReentrantLockTest.java create mode 100644 src/main/java/com/zerroi/test/ReentrantLockTest2.java create mode 100644 src/main/java/com/zerroi/test/ReentrantLockTest3.java create mode 100644 src/main/java/com/zerroi/test/ReentrantLockTest4.java create mode 100644 src/main/java/com/zerroi/test/Test12.java create mode 100644 src/main/java/com/zerroi/test/Test13.java create mode 100644 src/main/java/com/zerroi/test/Test14.java create mode 100644 src/main/java/com/zerroi/test/Test15.java create mode 100644 src/main/java/com/zerroi/test/Test16.java create mode 100644 src/main/java/com/zerroi/test/Test17.java create mode 100644 src/main/java/com/zerroi/test/Test4.java create mode 100644 src/main/java/com/zerroi/test/Test5.java create mode 100644 src/main/java/com/zerroi/test/Test6.java create mode 100644 src/main/java/com/zerroi/test/Test7.java create mode 100644 src/main/java/com/zerroi/test/Test8.java create mode 100644 src/main/java/com/zerroi/test/Test9.java create mode 100644 src/main/java/com/zerroi/test/TestBiased.java create mode 100644 src/main/java/com/zerroi/test/TestBiased2.java create mode 100644 src/main/java/com/zerroi/test/TestBiased3.java create mode 100644 src/main/java/com/zerroi/test/TestFrames.java create mode 100644 src/main/java/com/zerroi/test/TestJoin.java create mode 100644 src/main/java/com/zerroi/test/TestWaitAndNotify.java create mode 100644 src/main/java/com/zerroi/test/TestWaitNotify.java create mode 100644 src/main/java/com/zerroi/test/TwoPhaseCommit.java create mode 100644 src/main/java/com/zerroi/test/test3.java create mode 100644 src/main/resources/logback.xml create mode 100644 tmp/1.txt create mode 100644 tmp/10.txt create mode 100644 tmp/11.txt create mode 100644 tmp/12.txt create mode 100644 tmp/13.txt create mode 100644 tmp/14.txt create mode 100644 tmp/15.txt create mode 100644 tmp/16.txt create mode 100644 tmp/17.txt create mode 100644 tmp/18.txt create mode 100644 tmp/19.txt create mode 100644 tmp/2.txt create mode 100644 tmp/20.txt create mode 100644 tmp/21.txt create mode 100644 tmp/22.txt create mode 100644 tmp/23.txt create mode 100644 tmp/24.txt create mode 100644 tmp/25.txt create mode 100644 tmp/26.txt create mode 100644 tmp/3.txt create mode 100644 tmp/4.txt create mode 100644 tmp/5.txt create mode 100644 tmp/6.txt create mode 100644 tmp/7.txt create mode 100644 tmp/8.txt create mode 100644 tmp/9.txt diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..5ff6309 --- /dev/null +++ b/.gitignore @@ -0,0 +1,38 @@ +target/ +!.mvn/wrapper/maven-wrapper.jar +!**/src/main/**/target/ +!**/src/test/**/target/ + +### IntelliJ IDEA ### +.idea/modules.xml +.idea/jarRepositories.xml +.idea/compiler.xml +.idea/libraries/ +*.iws +*.iml +*.ipr + +### Eclipse ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ +build/ +!**/src/main/**/build/ +!**/src/test/**/build/ + +### VS Code ### +.vscode/ + +### Mac OS ### +.DS_Store \ No newline at end of file diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..13566b8 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/.idea/encodings.xml b/.idea/encodings.xml new file mode 100644 index 0000000..63574ec --- /dev/null +++ b/.idea/encodings.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/leetcode/editor.xml b/.idea/leetcode/editor.xml new file mode 100644 index 0000000..322b21a --- /dev/null +++ b/.idea/leetcode/editor.xml @@ -0,0 +1,42 @@ + + + + + + \ No newline at end of file diff --git a/.idea/leetcode/statistics.xml b/.idea/leetcode/statistics.xml new file mode 100644 index 0000000..4632265 --- /dev/null +++ b/.idea/leetcode/statistics.xml @@ -0,0 +1,20 @@ + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..132404b --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,14 @@ + + + + + + + + + + \ No newline at end of file diff --git a/.idea/uiDesigner.xml b/.idea/uiDesigner.xml new file mode 100644 index 0000000..2b63946 --- /dev/null +++ b/.idea/uiDesigner.xml @@ -0,0 +1,124 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..94a25f7 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..7af2380 --- /dev/null +++ b/pom.xml @@ -0,0 +1,36 @@ + + + 4.0.0 + + com.zerroi + concurrent_study + 1.0-SNAPSHOT + + + 1.8 + 1.8 + UTF-8 + + + + + org.projectlombok + lombok + 1.18.10 + + + ch.qos.logback + logback-classic + 1.2.3 + + + + org.openjdk.jol + jol-core + 0.16 + + + + \ No newline at end of file diff --git a/src/main/java/com/zerroi/alternateprint/Test1.java b/src/main/java/com/zerroi/alternateprint/Test1.java new file mode 100644 index 0000000..7a1359c --- /dev/null +++ b/src/main/java/com/zerroi/alternateprint/Test1.java @@ -0,0 +1,35 @@ +package com.zerroi.alternateprint; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j(topic = "c.Test1") +public class Test1 { + static final Object lock = new Object(); + static boolean isRun = false; + + public static void main(String[] args) { + Thread t1 = new Thread(() -> { + synchronized (lock) { + while (!isRun) { + try { + lock.wait(); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + } + log.debug("1"); + } + }, "t1"); + + Thread t2 = new Thread(() -> { + synchronized (lock) { + log.debug("2"); + isRun = true; + lock.notify(); + } + }, "t2"); + + t1.start(); + t2.start(); + } +} diff --git a/src/main/java/com/zerroi/alternateprint/Test2.java b/src/main/java/com/zerroi/alternateprint/Test2.java new file mode 100644 index 0000000..9046abd --- /dev/null +++ b/src/main/java/com/zerroi/alternateprint/Test2.java @@ -0,0 +1,44 @@ +package com.zerroi.alternateprint; + +import lombok.extern.slf4j.Slf4j; + +import java.util.concurrent.locks.Condition; +import java.util.concurrent.locks.ReentrantLock; + +@Slf4j(topic = "c.Test2") +public class Test2 { + private static final ReentrantLock lock = new ReentrantLock(); + private static final Condition condition = lock.newCondition(); + static boolean isRun = false; + public static void main(String[] args) { + Thread t1 = new Thread(() -> { + lock.lock(); + try { + while (!isRun) { + try { + condition.await(); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + } + log.debug("1"); + } finally { + lock.unlock(); + } + }, "t1"); + + Thread t2 = new Thread(() -> { + lock.lock(); + try { + log.debug("2"); + isRun = true; + condition.signal(); + } finally { + lock.unlock(); + } + }, "t2"); + + t1.start(); + t2.start(); + } +} diff --git a/src/main/java/com/zerroi/alternateprint/Test3.java b/src/main/java/com/zerroi/alternateprint/Test3.java new file mode 100644 index 0000000..c187103 --- /dev/null +++ b/src/main/java/com/zerroi/alternateprint/Test3.java @@ -0,0 +1,24 @@ +package com.zerroi.alternateprint; + +import lombok.extern.slf4j.Slf4j; + +import java.util.concurrent.locks.LockSupport; + +@Slf4j(topic = "c.Test3") +public class Test3 { + public static void main(String[] args) { + Thread t1 = new Thread(() -> { + LockSupport.park(); + log.debug("1"); + }, "t1"); + + Thread t2 = new Thread(() -> { + log.debug("2"); + LockSupport.unpark(t1); + }, "t2"); + + t1.start(); + t2.start(); +// waknjd + } +} diff --git a/src/main/java/com/zerroi/alternateprint/Test4.java b/src/main/java/com/zerroi/alternateprint/Test4.java new file mode 100644 index 0000000..2f21798 --- /dev/null +++ b/src/main/java/com/zerroi/alternateprint/Test4.java @@ -0,0 +1,49 @@ +package com.zerroi.alternateprint; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j(topic = "c.Test4") +public class Test4 { + public static void main(String[] args) { + WaitAndNotify waitAndNotify = new WaitAndNotify(5, 1); + new Thread(() -> { + waitAndNotify.print("a", 1, 2); + },"t1").start(); + + new Thread(() -> { + waitAndNotify.print("b", 2, 3); + },"t2").start(); + + new Thread(() -> { + waitAndNotify.print("c", 3, 1); + },"t3").start(); + } +} + +@Slf4j(topic = "c.WaitAndNotify") +class WaitAndNotify { + public void print(String str, int waitFlag, int nextFlag) { + for (int i = 0; i < loop; i++) { + synchronized (this) { + while (waitFlag != flag) { + try { + this.wait(); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + } + log.debug(str); + flag = nextFlag; + this.notifyAll(); + } + } + } + + public WaitAndNotify(int loop, int flag) { + this.loop = loop; + this.flag = flag; + } + + private final int loop; + private int flag; +} diff --git a/src/main/java/com/zerroi/alternateprint/Test5.java b/src/main/java/com/zerroi/alternateprint/Test5.java new file mode 100644 index 0000000..d23d0d0 --- /dev/null +++ b/src/main/java/com/zerroi/alternateprint/Test5.java @@ -0,0 +1,60 @@ +package com.zerroi.alternateprint; + +import lombok.extern.slf4j.Slf4j; + +import java.util.concurrent.locks.Condition; +import java.util.concurrent.locks.ReentrantLock; + +public class Test5 { + public static void main(String[] args) throws InterruptedException { + AwaitSignal awaitSignal = new AwaitSignal(5); + + Condition a = awaitSignal.newCondition(); + Condition b = awaitSignal.newCondition(); + Condition c = awaitSignal.newCondition(); + + new Thread(() -> { + awaitSignal.print("a", a, b); + }, "A").start(); + + new Thread(() -> { + awaitSignal.print("b", b, c); + }, "B").start(); + + new Thread(() -> { + awaitSignal.print("c", c, a); + }, "C").start(); + + Thread.sleep(1000); + awaitSignal.lock(); + try { + a.signal(); + } finally { + awaitSignal.unlock(); + } + } +} + +@Slf4j(topic = "c.AwaitSignal") +class AwaitSignal extends ReentrantLock { + private final int loop; + + public AwaitSignal(int loop) { + this.loop = loop; + } + + public void print(String str, Condition cur, Condition next) { + for (int i = 0; i < loop; i++) { + lock(); + try { + cur.await(); + log.debug(str); + next.signal(); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } finally { + unlock(); + } + } + } +} diff --git a/src/main/java/com/zerroi/alternateprint/Test6.java b/src/main/java/com/zerroi/alternateprint/Test6.java new file mode 100644 index 0000000..996e68a --- /dev/null +++ b/src/main/java/com/zerroi/alternateprint/Test6.java @@ -0,0 +1,50 @@ +package com.zerroi.alternateprint; + +import lombok.extern.slf4j.Slf4j; + +import java.util.concurrent.locks.LockSupport; + +public class Test6 { + static Thread t1; + static Thread t2; + static Thread t3; + + public static void main(String[] args) { + ParkUnpark parkUnpark = new ParkUnpark(5); + t1 = new Thread(() -> { + parkUnpark.print("A", t2); + }, "t1"); + + t2 = new Thread(() -> { + parkUnpark.print("B", t3); + }, "t2"); + + t3 = new Thread(() -> { + parkUnpark.print("C", t1); + }, "t3"); + + t1.start(); + t2.start(); + t3.start(); + + LockSupport.unpark(t1); + } +} + +@Slf4j(topic = "c.ParkUnpark") +class ParkUnpark { + + public void print(String str, Thread next) { + for (int i = 0; i < loop; i++) { + LockSupport.park(); + log.info(str); + LockSupport.unpark(next); + } + } + + private final int loop; + + public ParkUnpark(int loop) { + this.loop = loop; + } +} diff --git a/src/main/java/com/zerroi/charpter05/Test1.java b/src/main/java/com/zerroi/charpter05/Test1.java new file mode 100644 index 0000000..cd8d304 --- /dev/null +++ b/src/main/java/com/zerroi/charpter05/Test1.java @@ -0,0 +1,18 @@ +package com.zerroi.charpter05; + +import static java.lang.Thread.sleep; + +public class Test1 { + volatile static boolean run = true; + public static void main(String[] args) throws InterruptedException { + Thread t1 = new Thread(() -> { + while (run) { + + } + }, "t1"); + t1.start(); + sleep(1000); + System.out.println("stop t1"); + run = false; + } +} diff --git a/src/main/java/com/zerroi/charpter06/LockCas.java b/src/main/java/com/zerroi/charpter06/LockCas.java new file mode 100644 index 0000000..a5cb94e --- /dev/null +++ b/src/main/java/com/zerroi/charpter06/LockCas.java @@ -0,0 +1,50 @@ +package com.zerroi.charpter06; + +import lombok.extern.slf4j.Slf4j; + +import java.util.concurrent.atomic.AtomicInteger; + +import static java.lang.Thread.sleep; + +@Slf4j(topic = "c.LockCas") +public class LockCas { + private AtomicInteger state = new AtomicInteger(0); + public void lock() { + while (true) { + if (state.compareAndSet(0, 1)) { + break; + } + } + } + + public void unlock() { + log.debug("unlock...."); + state.set(0); + } + + public static void main(String[] args) { + LockCas lock = new LockCas(); + new Thread(() -> { + log.debug("begin..."); + lock.lock(); + try { + log.debug("lock"); + sleep(1000); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } finally { + lock.unlock(); + } + }, "t1").start(); + + new Thread(() -> { + log.debug("begin..."); + lock.lock(); + try { + log.debug("lock"); + } finally { + lock.unlock(); + } + }, "t2").start(); + } +} diff --git a/src/main/java/com/zerroi/charpter06/Test0.java b/src/main/java/com/zerroi/charpter06/Test0.java new file mode 100644 index 0000000..728087a --- /dev/null +++ b/src/main/java/com/zerroi/charpter06/Test0.java @@ -0,0 +1,90 @@ +package com.zerroi.charpter06; + +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.atomic.AtomicInteger; + +public class Test0 { + public static void main(String[] args) { + Account account = new AccountCas(10000); + Account.demo(account); + } +} + +class AccountCas implements Account { + private AtomicInteger balance; + + public AccountCas(int balance) { + this.balance = new AtomicInteger(balance); + } + + @Override + public Integer getBalance() { + return balance.get(); + } + + @Override + public void withdraw(Integer amount) { + /*while (true) { + int pre = balance.get(); + int next = pre - amount; + + boolean isUpdated = balance.compareAndSet(pre, next); + if (isUpdated) { + break; + } + }*/ + balance.getAndAdd(-1 * amount); + } +} + +interface Account { + // 获取余额 + Integer getBalance(); + + // 取款 + void withdraw(Integer amount); + + /** + * 方法内会启动 1000 个线程,每个线程做 -10 元 的操作 + * 如果初始余额为 10000 那么正确的结果应当是 0 + */ + static void demo(Account account) { + List ts = new ArrayList<>(); + long start = System.nanoTime(); + for (int i = 0; i < 1000; i++) { + ts.add(new Thread(() -> { + account.withdraw(10); + })); + } + ts.forEach(Thread::start); + ts.forEach(t -> { + try { + t.join(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + }); + long end = System.nanoTime(); + System.out.println(account.getBalance() + + " cost: " + (end - start) / 1000_000 + " ms"); + } +} + +class AccountUnsafe implements Account { + private Integer balance; + + public AccountUnsafe(Integer balance) { + this.balance = balance; + } + + @Override + public Integer getBalance() { + return balance; + } + + @Override + public void withdraw(Integer amount) { + balance -= amount; + } +} diff --git a/src/main/java/com/zerroi/charpter06/Test1.java b/src/main/java/com/zerroi/charpter06/Test1.java new file mode 100644 index 0000000..82420a5 --- /dev/null +++ b/src/main/java/com/zerroi/charpter06/Test1.java @@ -0,0 +1,29 @@ +package com.zerroi.charpter06; + +import java.util.concurrent.atomic.AtomicInteger; +import java.util.function.IntUnaryOperator; + +public class Test1 { + public static void main(String[] args) { + AtomicInteger integer = new AtomicInteger(5); +// System.out.println(integer.incrementAndGet()); +// System.out.println(integer.getAndIncrement()); + +// System.out.println(integer.getAndAdd(5)); +// System.out.println(integer.addAndGet(5)); + +// System.out.println(integer.updateAndGet(x -> x * 5)); + System.out.println(updateAndGet(integer, pre -> pre / 2)); + System.out.println(integer.get()); + } + + public static int updateAndGet(AtomicInteger integer, IntUnaryOperator operator) { + while (true) { + int pre = integer.get(); + int next = operator.applyAsInt(pre); + if (integer.compareAndSet(pre, next)) { + return next; + } + } + } +} diff --git a/src/main/java/com/zerroi/charpter06/Test2.java b/src/main/java/com/zerroi/charpter06/Test2.java new file mode 100644 index 0000000..d67e040 --- /dev/null +++ b/src/main/java/com/zerroi/charpter06/Test2.java @@ -0,0 +1,69 @@ +package com.zerroi.charpter06; + +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.atomic.AtomicReference; + +public class Test2 { + public static void main(String[] args) { + DecimalAccount.demo(new DecimalAccountCas(new BigDecimal("10000"))); + } +} + +class DecimalAccountCas implements DecimalAccount { + private AtomicReference balance; + + public DecimalAccountCas(BigDecimal balance) { + this.balance = new AtomicReference<>(balance); + } + + @Override + public BigDecimal getBalance() { + return balance.get(); + } + + @Override + public void withdraw(BigDecimal amount) { + while (true) { + BigDecimal pre = balance.get(); + BigDecimal next = pre.subtract(amount); + if (balance.compareAndSet(pre, next)) { + break; + } + } + } +} + +interface DecimalAccount { + // 获取余额 + BigDecimal getBalance(); + + // 取款 + void withdraw(BigDecimal amount); + + /** + * 方法内会启动 1000 个线程,每个线程做 -10 元 的操作 + * 如果初始余额为 10000 那么正确的结果应当是 0 + */ + static void demo(DecimalAccount account) { + List ts = new ArrayList<>(); + long start = System.nanoTime(); + for (int i = 0; i < 1000; i++) { + ts.add(new Thread(() -> { + account.withdraw(BigDecimal.valueOf(10)); + })); + } + ts.forEach(Thread::start); + ts.forEach(t -> { + try { + t.join(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + }); + long end = System.nanoTime(); + System.out.println(account.getBalance() + + " cost: " + (end - start) / 1000_000 + " ms"); + } +} diff --git a/src/main/java/com/zerroi/charpter06/Test3.java b/src/main/java/com/zerroi/charpter06/Test3.java new file mode 100644 index 0000000..c7de662 --- /dev/null +++ b/src/main/java/com/zerroi/charpter06/Test3.java @@ -0,0 +1,16 @@ +package com.zerroi.charpter06; + +import java.util.concurrent.atomic.AtomicReference; + +import static java.lang.Thread.sleep; + +public class Test3 { + static AtomicReference ref = new AtomicReference<>("A"); + public static void main(String[] args) throws InterruptedException { + System.out.println("start...."); + String pre = ref.get(); + sleep(1000); + System.out.println(ref.compareAndSet(pre, "A")); + System.out.println(ref.get()); + } +} diff --git a/src/main/java/com/zerroi/charpter06/Test4.java b/src/main/java/com/zerroi/charpter06/Test4.java new file mode 100644 index 0000000..12a4c35 --- /dev/null +++ b/src/main/java/com/zerroi/charpter06/Test4.java @@ -0,0 +1,37 @@ +package com.zerroi.charpter06; + +import lombok.extern.slf4j.Slf4j; + +import java.util.concurrent.atomic.AtomicStampedReference; + +import static java.lang.Thread.sleep; + +@Slf4j(topic = "c.Test4") +public class Test4 { + static AtomicStampedReference reference = new AtomicStampedReference<>("A", 0); + + public static void main(String[] args) throws InterruptedException { + log.debug("main start...."); + int stamp = reference.getStamp(); + log.debug("{}", stamp); + String pre = reference.getReference(); + + other(); + sleep(1000); + log.debug("A->C {}", reference.compareAndSet(pre, "C", stamp, stamp + 1)); + } + + private static void other() throws InterruptedException { + new Thread(() -> { + int stamp = reference.getStamp(); + log.debug("{}", stamp); + log.debug("A->B {}", reference.compareAndSet(reference.getReference(), "B", stamp, stamp + 1)); + }, "t1").start(); + sleep(500); + new Thread(() -> { + int stamp = reference.getStamp(); + log.debug("{}", stamp); + log.debug("B->A {}", reference.compareAndSet(reference.getReference(), "A", stamp, stamp + 1)); + }, "t2").start(); + } +} diff --git a/src/main/java/com/zerroi/charpter06/Test5.java b/src/main/java/com/zerroi/charpter06/Test5.java new file mode 100644 index 0000000..4aa88bb --- /dev/null +++ b/src/main/java/com/zerroi/charpter06/Test5.java @@ -0,0 +1,48 @@ +package com.zerroi.charpter06; + +import lombok.extern.slf4j.Slf4j; + +import java.util.concurrent.atomic.AtomicMarkableReference; + +@Slf4j(topic = "c.Test5") +public class Test5 { + public static void main(String[] args) throws InterruptedException { + GarbageBag bag = new GarbageBag("装满了垃圾"); +// 参数2 mark 可以看作一个标记,表示垃圾袋满了 + AtomicMarkableReference ref = new AtomicMarkableReference<>(bag, true); + log.debug("主线程 start..."); + GarbageBag prev = ref.getReference(); + log.debug(prev.toString()); + + new Thread(() -> { + log.debug("打扫卫生的线程 start..."); + bag.setDesc("空垃圾袋"); + while (!ref.compareAndSet(bag, bag, true, false)) { + } + log.debug(bag.toString()); + }).start(); + + Thread.sleep(1000); + log.debug("主线程想换一只新垃圾袋?"); + boolean success = ref.compareAndSet(prev, new GarbageBag("空垃圾袋"), true, false); + log.debug("换了么?" + success); + log.debug(ref.getReference().toString()); + } +} + +class GarbageBag { + String desc; + + public GarbageBag(String desc) { + this.desc = desc; + } + + public void setDesc(String desc) { + this.desc = desc; + } + + @Override + public String toString() { + return super.toString() + " " + desc; + } +} diff --git a/src/main/java/com/zerroi/charpter06/Test6.java b/src/main/java/com/zerroi/charpter06/Test6.java new file mode 100644 index 0000000..696a7ce --- /dev/null +++ b/src/main/java/com/zerroi/charpter06/Test6.java @@ -0,0 +1,24 @@ +package com.zerroi.charpter06; + +import lombok.ToString; +import lombok.extern.slf4j.Slf4j; + +import java.util.concurrent.atomic.AtomicReferenceFieldUpdater; + +@Slf4j(topic = "c.Test6") +public class Test6 { + public static void main(String[] args) { + Student student = new Student(); + AtomicReferenceFieldUpdater updater = + AtomicReferenceFieldUpdater.newUpdater(Student.class, String.class, "name"); + System.out.println(updater.compareAndSet(student, null, "张三")); + System.out.println(student); + + } +} + +@ToString +class Student { + volatile String name; + +} diff --git a/src/main/java/com/zerroi/charpter06/Test7.java b/src/main/java/com/zerroi/charpter06/Test7.java new file mode 100644 index 0000000..dfb215f --- /dev/null +++ b/src/main/java/com/zerroi/charpter06/Test7.java @@ -0,0 +1,50 @@ +package com.zerroi.charpter06; + +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.atomic.AtomicLong; +import java.util.concurrent.atomic.LongAdder; +import java.util.function.Consumer; +import java.util.function.Supplier; + +public class Test7 { + public static void main(String[] args) { + for (int i = 0; i < 5; i++) { + demo( + () -> new AtomicLong(0), + AtomicLong::getAndIncrement + ); + } + for (int i = 0; i < 5; i++) { + demo( + LongAdder::new, + LongAdder::increment + ); + } + } + + private static void demo(Supplier adderSupplier, Consumer action) { + T adder = adderSupplier.get(); + long start = System.nanoTime(); + List ts = new ArrayList<>(); +// 4 个线程,每人累加 50 万 + for (int i = 0; i < 40; i++) { + ts.add(new Thread(() -> { + for (int j = 0; j < 500000; j++) { + action.accept(adder); + } + })); + } + ts.forEach(t -> t.start()); + ts.forEach(t -> { + try { + t.join(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + }); + long end = System.nanoTime(); + System.out.println(adder + " cost:" + (end - start)/1000_000); + } +} + diff --git a/src/main/java/com/zerroi/charpter06/Test8.java b/src/main/java/com/zerroi/charpter06/Test8.java new file mode 100644 index 0000000..7218f04 --- /dev/null +++ b/src/main/java/com/zerroi/charpter06/Test8.java @@ -0,0 +1,51 @@ +package com.zerroi.charpter06; + +import lombok.Getter; +import lombok.extern.slf4j.Slf4j; +import sun.misc.Unsafe; + +public class Test8 { + public static void main(String[] args) { + Account.demo(new MyAtomicInteger(10000)); + } +} + +@Getter +@Slf4j(topic = "c.MyAtomicInteger") +class MyAtomicInteger implements Account{ + private volatile int value; + private static long valueOffset; + static final Unsafe UNSAFE; + public MyAtomicInteger(int value) { + this.value = value; + } + + static { + UNSAFE = UnsafeAccessor.getUnsafe(); + try { + valueOffset = UNSAFE.objectFieldOffset(MyAtomicInteger.class.getDeclaredField("value")); + } catch (NoSuchFieldException e) { + log.error("error: ", e); + throw new RuntimeException(e); + } + } + public void decrement(int amount) { + while (true) { + int pre = this.value; + int next = pre - amount; + if (UNSAFE.compareAndSwapInt(this, valueOffset, pre, next)) { + break; + } + } + } + + @Override + public Integer getBalance() { + return getValue(); + } + + @Override + public void withdraw(Integer amount) { + decrement(amount); + } +} diff --git a/src/main/java/com/zerroi/charpter06/TestUnSafe.java b/src/main/java/com/zerroi/charpter06/TestUnSafe.java new file mode 100644 index 0000000..49a8aee --- /dev/null +++ b/src/main/java/com/zerroi/charpter06/TestUnSafe.java @@ -0,0 +1,30 @@ +package com.zerroi.charpter06; + +import lombok.Data; +import sun.misc.Unsafe; + +import java.lang.reflect.Field; + +public class TestUnSafe { + public static void main(String[] args) throws Exception { + Field theUnsafe = Unsafe.class.getDeclaredField("theUnsafe"); + theUnsafe.setAccessible(true); + Unsafe unsafe = (Unsafe) theUnsafe.get(null); + + System.out.println(unsafe); +// 获取域的偏移地址 + long idOffset = unsafe.objectFieldOffset(Teacher.class.getDeclaredField("id")); + long nameOffset = unsafe.objectFieldOffset(Teacher.class.getDeclaredField("name")); + Teacher teacher = new Teacher(); + unsafe.compareAndSwapInt(teacher, idOffset, 0, 1); + unsafe.compareAndSwapObject(teacher, nameOffset, null, "Rocky"); + + System.out.println(teacher); + } + +} +@Data +class Teacher { + volatile int id; + volatile String name; +} diff --git a/src/main/java/com/zerroi/charpter06/UnsafeAccessor.java b/src/main/java/com/zerroi/charpter06/UnsafeAccessor.java new file mode 100644 index 0000000..89190c6 --- /dev/null +++ b/src/main/java/com/zerroi/charpter06/UnsafeAccessor.java @@ -0,0 +1,23 @@ +package com.zerroi.charpter06; + + +import lombok.Getter; +import sun.misc.Unsafe; + +import java.lang.reflect.Field; + +public class UnsafeAccessor { + @Getter + private static final Unsafe unsafe; + + static { + try { + Field theUnsafe = Unsafe.class.getDeclaredField("theUnsafe"); + theUnsafe.setAccessible(true); + unsafe = (Unsafe) theUnsafe.get(null); + } catch (NoSuchFieldException | IllegalAccessException e) { + throw new Error(e); + } + } + +} diff --git a/src/main/java/com/zerroi/charpter07/Test1.java b/src/main/java/com/zerroi/charpter07/Test1.java new file mode 100644 index 0000000..a307e74 --- /dev/null +++ b/src/main/java/com/zerroi/charpter07/Test1.java @@ -0,0 +1,35 @@ +package com.zerroi.charpter07; + +import lombok.extern.slf4j.Slf4j; + +import java.text.SimpleDateFormat; +import java.time.format.DateTimeFormatter; +import java.time.temporal.TemporalAccessor; + +@Slf4j(topic = "c.Test1") +public class Test1 { + public static void main(String[] args) { + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd"); + for (int i = 0; i < 10; i++) { + new Thread(() -> { + TemporalAccessor parse = formatter.parse("1951-04-21"); + log.debug("data:{}", parse); + }, "t" + i).start(); + } + } + + public static void test() { + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); + for (int i = 0; i < 10; i++) { + new Thread(() -> { + synchronized (sdf) { + try { + log.debug("{}", sdf.parse("1951-04-21")); + } catch (Exception e) { + log.error(String.valueOf(e)); + } + } + }).start(); + } + } +} diff --git a/src/main/java/com/zerroi/charpter07/Test2.java b/src/main/java/com/zerroi/charpter07/Test2.java new file mode 100644 index 0000000..db64fae --- /dev/null +++ b/src/main/java/com/zerroi/charpter07/Test2.java @@ -0,0 +1,367 @@ +package com.zerroi.charpter07; + +import lombok.extern.slf4j.Slf4j; + +import java.sql.*; +import java.util.Map; +import java.util.Properties; +import java.util.Random; +import java.util.concurrent.Executor; +import java.util.concurrent.atomic.AtomicIntegerArray; + +public class Test2 { + public static void main(String[] args) { + Pool pool = new Pool(2); + for (int i = 0; i < 5; i++) { + new Thread(() -> { + Connection connection = pool.borrow(); + try { + Thread.sleep(new Random().nextInt(1000)); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + pool.returnConn(connection); + }, "t" + i).start(); + } + } +} + +@Slf4j(topic = "c.Pool") +class Pool { +// 连接池的大小 + private final int poolSize; +// 连接对象数组 + private Connection[] connections; +// 连接状态数组 0->空闲,1->繁忙 + private AtomicIntegerArray status; + + public Pool(int poolSize) { + this.poolSize = poolSize; + this.status = new AtomicIntegerArray(new int[poolSize]); + this.connections = new Connection[poolSize]; + for (int i = 0; i < poolSize; i++) { + connections[i] = new MockConnection("连接对象" + (i+1)); + } + } + +// 借连接 + public Connection borrow() { + while (true) { + for (int i = 0; i < poolSize; i++) { + if (status.get(i) == 0) { + if (status.compareAndSet(i, 0, 1)) { + log.debug("获取连接:{}", connections[i]); + return connections[i]; + } + } + } +// 如果没有空闲连接,当前线程进入等待 + synchronized (this) { + try { + log.debug("等待连接...."); + this.wait(); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + } + } + } +// 返还连接 + public void returnConn(Connection conn) { + for (int i = 0; i < connections.length; i++) { + if (connections[i] == conn) { + status.set(i, 0); + synchronized (this) { + log.debug("归还连接:{}", conn); + this.notifyAll(); + } + break; + } + } + } +} + +class MockConnection implements Connection { + private String name; + + public MockConnection(String name) { + this.name = name; + } + + @Override + public String toString() { + return "MockConnection{" + + "name='" + name + '\'' + + '}'; + } + + @Override + public Statement createStatement() throws SQLException { + return null; + } + + @Override + public PreparedStatement prepareStatement(String sql) throws SQLException { + return null; + } + + @Override + public CallableStatement prepareCall(String sql) throws SQLException { + return null; + } + + @Override + public String nativeSQL(String sql) throws SQLException { + return null; + } + + @Override + public void setAutoCommit(boolean autoCommit) throws SQLException { + + } + + @Override + public boolean getAutoCommit() throws SQLException { + return false; + } + + @Override + public void commit() throws SQLException { + + } + + @Override + public void rollback() throws SQLException { + + } + + @Override + public void close() throws SQLException { + + } + + @Override + public boolean isClosed() throws SQLException { + return false; + } + + @Override + public DatabaseMetaData getMetaData() throws SQLException { + return null; + } + + @Override + public void setReadOnly(boolean readOnly) throws SQLException { + + } + + @Override + public boolean isReadOnly() throws SQLException { + return false; + } + + @Override + public void setCatalog(String catalog) throws SQLException { + + } + + @Override + public String getCatalog() throws SQLException { + return null; + } + + @Override + public void setTransactionIsolation(int level) throws SQLException { + + } + + @Override + public int getTransactionIsolation() throws SQLException { + return 0; + } + + @Override + public SQLWarning getWarnings() throws SQLException { + return null; + } + + @Override + public void clearWarnings() throws SQLException { + + } + + @Override + public Statement createStatement(int resultSetType, int resultSetConcurrency) throws SQLException { + return null; + } + + @Override + public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency) throws SQLException { + return null; + } + + @Override + public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency) throws SQLException { + return null; + } + + @Override + public Map> getTypeMap() throws SQLException { + return null; + } + + @Override + public void setTypeMap(Map> map) throws SQLException { + + } + + @Override + public void setHoldability(int holdability) throws SQLException { + + } + + @Override + public int getHoldability() throws SQLException { + return 0; + } + + @Override + public Savepoint setSavepoint() throws SQLException { + return null; + } + + @Override + public Savepoint setSavepoint(String name) throws SQLException { + return null; + } + + @Override + public void rollback(Savepoint savepoint) throws SQLException { + + } + + @Override + public void releaseSavepoint(Savepoint savepoint) throws SQLException { + + } + + @Override + public Statement createStatement(int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException { + return null; + } + + @Override + public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException { + return null; + } + + @Override + public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException { + return null; + } + + @Override + public PreparedStatement prepareStatement(String sql, int autoGeneratedKeys) throws SQLException { + return null; + } + + @Override + public PreparedStatement prepareStatement(String sql, int[] columnIndexes) throws SQLException { + return null; + } + + @Override + public PreparedStatement prepareStatement(String sql, String[] columnNames) throws SQLException { + return null; + } + + @Override + public Clob createClob() throws SQLException { + return null; + } + + @Override + public Blob createBlob() throws SQLException { + return null; + } + + @Override + public NClob createNClob() throws SQLException { + return null; + } + + @Override + public SQLXML createSQLXML() throws SQLException { + return null; + } + + @Override + public boolean isValid(int timeout) throws SQLException { + return false; + } + + @Override + public void setClientInfo(String name, String value) throws SQLClientInfoException { + + } + + @Override + public void setClientInfo(Properties properties) throws SQLClientInfoException { + + } + + @Override + public String getClientInfo(String name) throws SQLException { + return null; + } + + @Override + public Properties getClientInfo() throws SQLException { + return null; + } + + @Override + public Array createArrayOf(String typeName, Object[] elements) throws SQLException { + return null; + } + + @Override + public Struct createStruct(String typeName, Object[] attributes) throws SQLException { + return null; + } + + @Override + public void setSchema(String schema) throws SQLException { + + } + + @Override + public String getSchema() throws SQLException { + return null; + } + + @Override + public void abort(Executor executor) throws SQLException { + + } + + @Override + public void setNetworkTimeout(Executor executor, int milliseconds) throws SQLException { + + } + + @Override + public int getNetworkTimeout() throws SQLException { + return 0; + } + + @Override + public T unwrap(Class iface) throws SQLException { + return null; + } + + @Override + public boolean isWrapperFor(Class iface) throws SQLException { + return false; + } +} \ No newline at end of file diff --git a/src/main/java/com/zerroi/charpter08/TestAQS.java b/src/main/java/com/zerroi/charpter08/TestAQS.java new file mode 100644 index 0000000..bda9824 --- /dev/null +++ b/src/main/java/com/zerroi/charpter08/TestAQS.java @@ -0,0 +1,74 @@ +package com.zerroi.charpter08; + +import java.util.concurrent.TimeUnit; +import java.util.concurrent.locks.AbstractQueuedSynchronizer; +import java.util.concurrent.locks.Condition; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; + +public class TestAQS { + public static void main(String[] args) { + ReentrantLock lock = new ReentrantLock(); + + } +} + +class MyLock implements Lock { + class MySync extends AbstractQueuedSynchronizer { + @Override + protected boolean tryAcquire(int arg) { + if (compareAndSetState(0, 1)) { + setExclusiveOwnerThread(Thread.currentThread()); + return true; + } + return false; + } + + @Override + protected boolean tryRelease(int arg) { + setExclusiveOwnerThread(null); + setState(0); + return true; + } + + @Override + protected boolean isHeldExclusively() { + return getState() == 1; + } + + public Condition newCondition() { + return new ConditionObject(); + } + } + private MySync sync = new MySync(); + + @Override + public void lock() { + sync.acquire(1); + } + + @Override + public void lockInterruptibly() throws InterruptedException { + sync.acquireInterruptibly(1); + } + + @Override + public boolean tryLock() { + return sync.tryAcquire(1); + } + + @Override + public boolean tryLock(long time, TimeUnit unit) throws InterruptedException { + return false; + } + + @Override + public void unlock() { + + } + + @Override + public Condition newCondition() { + return null; + } +} diff --git a/src/main/java/com/zerroi/charpter08/TestConcurrentHashMap.java b/src/main/java/com/zerroi/charpter08/TestConcurrentHashMap.java new file mode 100644 index 0000000..dc92f0d --- /dev/null +++ b/src/main/java/com/zerroi/charpter08/TestConcurrentHashMap.java @@ -0,0 +1,75 @@ +package com.zerroi.charpter08; + +import java.io.*; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.*; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.atomic.LongAdder; +import java.util.function.BiConsumer; +import java.util.function.Supplier; +import java.util.stream.Collectors; + +public class TestConcurrentHashMap { + static final String ALPHA = "abcedfghijklmnopqrstuvwxyz"; + + public static void main(String[] args) { + demo( + // 创建 map 集合 + // 创建 ConcurrentHashMap 对不对? + () -> new ConcurrentHashMap(), + // 进行计数 + (map, words) -> { + for (String word : words) { + LongAdder value = map.computeIfAbsent(word, (key) -> new LongAdder()); + value.increment(); + /*Integer counter = map.get(word); + int newValue = counter == null ? 1 : counter + 1; + map.put(word, newValue);*/ + } + } + ); + } + + private static void demo(Supplier> supplier, + BiConsumer, List> consumer) { + Map counterMap = supplier.get(); + List ts = new ArrayList<>(); + for (int i = 1; i <= 26; i++) { + int idx = i; + Thread thread = new Thread(() -> { + List words = readFromFile(idx); + consumer.accept(counterMap, words); + }); + ts.add(thread); + } + ts.forEach(t -> t.start()); + ts.forEach(t -> { + try { + t.join(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + }); + System.out.println(counterMap); + } + + public static List readFromFile(int i) { + ArrayList words = new ArrayList<>(); + try (BufferedReader in = new BufferedReader(new InputStreamReader(new FileInputStream("tmp/" + + i + ".txt")))) { + while (true) { + String word = in.readLine(); + if (word == null) { + break; + } + words.add(word); + } + return words; + } catch (IOException e) { + throw new RuntimeException(e); + } + } +} + + diff --git a/src/main/java/com/zerroi/charpter08/TestForkJoin.java b/src/main/java/com/zerroi/charpter08/TestForkJoin.java new file mode 100644 index 0000000..cc18099 --- /dev/null +++ b/src/main/java/com/zerroi/charpter08/TestForkJoin.java @@ -0,0 +1,29 @@ +package com.zerroi.charpter08; + +import java.util.concurrent.ForkJoinPool; +import java.util.concurrent.RecursiveTask; + +public class TestForkJoin { + public static void main(String[] args) { + ForkJoinPool pool = new ForkJoinPool(4); + System.out.println(pool.invoke(new MyTask(5))); + } +} + +class MyTask extends RecursiveTask { + private int n; + + public MyTask(int n) { + this.n = n; + } + + @Override + protected Integer compute() { + if (n == 1) { + return 1; + } + MyTask t1 = new MyTask(n - 1); + t1.fork(); + return n + t1.join(); + } +} diff --git a/src/main/java/com/zerroi/charpter08/TestPool.java b/src/main/java/com/zerroi/charpter08/TestPool.java new file mode 100644 index 0000000..e6f87bb --- /dev/null +++ b/src/main/java/com/zerroi/charpter08/TestPool.java @@ -0,0 +1,192 @@ +package com.zerroi.charpter08; + +import lombok.extern.slf4j.Slf4j; + +import java.util.ArrayDeque; +import java.util.Deque; +import java.util.HashSet; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.locks.Condition; +import java.util.concurrent.locks.ReentrantLock; + +@Slf4j(topic = "c.TestPool") +public class TestPool { + public static void main(String[] args) { + ThreadPool threadPool = new ThreadPool(2, 1000, TimeUnit.MILLISECONDS, 10, (queue, task) -> { + + }); + for (int i = 0; i < 15; i++) { + int j = i; + threadPool.execute(() -> { + log.debug("{}", j); + }); + } + } +} + +@FunctionalInterface +interface RejectPolicy { + void reject(BlockingQueue queue, T task); +} + +@Slf4j(topic = "c.ThreadPool") +class ThreadPool { + private BlockingQueue taskQueue; + private HashSet workers = new HashSet<>(); + private int coreThreads; + private long timeout; + private TimeUnit timeUnit; + private RejectPolicy rejectPolicy; + + public synchronized void execute(Runnable task) { + if (workers.size() < coreThreads) { + log.debug("新增worker:{},{}", workers, task); + Worker worker = new Worker(task); + workers.add(worker); + worker.start(); + } else { + log.debug("加入任务队列:{}", task); +// taskQueue.put(task); + taskQueue.tryPut(rejectPolicy, task); + } + } + + public ThreadPool(int coreThreads, long timeout, TimeUnit timeUnit, int queueCapacity, RejectPolicy rejectPolicy) { + this.coreThreads = coreThreads; + this.timeout = timeout; + this.timeUnit = timeUnit; + this.taskQueue = new BlockingQueue<>(queueCapacity); + this.rejectPolicy = rejectPolicy; + } + + class Worker extends Thread { + private Runnable task; + + public Worker(Runnable task) { + this.task = task; + } + + @Override + public void run() { + while (task != null || (task = taskQueue.take()) != null) { + try { + log.debug("正在执行任务:{}", task); + task.run(); + } catch (Exception e) { + e.printStackTrace(); + } finally { + task = null; + } + } + synchronized (workers) { + log.debug("worker被移除:{}", this); + workers.remove(this); + } + } + } +} + +class BlockingQueue { + // 任务队列 + private Deque queue = new ArrayDeque<>(); + // 锁 + private ReentrantLock lock = new ReentrantLock(); + // 生产者条件变量 + private Condition fullWaitSet = lock.newCondition(); + // 消费者条件变量 + private Condition emptyWaitSet = lock.newCondition(); + // 队列容量 + private int capacity; + + public BlockingQueue(int queueCapacity) { + this.capacity = queueCapacity; + } + + // 带超时的阻塞获取 + public T poll(long timeout, TimeUnit unit) { + lock.lock(); + try { + long nanos = unit.toNanos(timeout); + while (queue.isEmpty()) { + nanos = emptyWaitSet.awaitNanos(nanos); + } + fullWaitSet.signal(); + return queue.removeFirst(); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } finally { + lock.unlock(); + } + } + + // 阻塞获取 + T take() { + lock.lock(); + try { + while (queue.isEmpty()) { + emptyWaitSet.await(); + } + fullWaitSet.signal(); + return queue.removeFirst(); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } finally { + lock.unlock(); + } + } + + // 阻塞添加 + void put(T task) { + lock.lock(); + try { + while (queue.size() == capacity) { + fullWaitSet.await(); + } + queue.addLast(task); + emptyWaitSet.signal(); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } finally { + lock.unlock(); + } + } + + boolean offer(T task, long timeout, TimeUnit timeUnit) { + lock.lock(); + try { + long nanos = timeUnit.toNanos(timeout); + while (queue.size() == capacity) { + if (nanos <= 0) { + return false; + } + nanos = fullWaitSet.awaitNanos(nanos); + } + queue.addLast(task); + emptyWaitSet.signal(); + return true; + } catch (InterruptedException e) { + throw new RuntimeException(e); + } finally { + lock.unlock(); + } + } + + // 队列大小 + int size() { + return queue.size(); + } + + public void tryPut(RejectPolicy rejectPolicy, T task) { + lock.lock(); + try { + if (queue.size() == capacity) { + rejectPolicy.reject(this, task); + } else { + queue.addLast(task); + emptyWaitSet.signal(); + } + } catch (Exception e) { + throw new RuntimeException(e); + } + } +} \ No newline at end of file diff --git a/src/main/java/com/zerroi/charpter08/TestReadWriteLock.java b/src/main/java/com/zerroi/charpter08/TestReadWriteLock.java new file mode 100644 index 0000000..317c367 --- /dev/null +++ b/src/main/java/com/zerroi/charpter08/TestReadWriteLock.java @@ -0,0 +1,64 @@ +package com.zerroi.charpter08; + +import lombok.extern.slf4j.Slf4j; + +import java.util.concurrent.locks.ReentrantReadWriteLock; + +public class TestReadWriteLock { + public static void main(String[] args) { + DataContainer dataContainer = new DataContainer(new Object()); + new Thread(() -> { + dataContainer.write(new Object()); + }, "t1").start(); + + try { + Thread.sleep(100); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + new Thread(() -> { + dataContainer.write(new Object()); + }, "t2").start(); + } +} +@Slf4j +class DataContainer { + private Object data; + private ReentrantReadWriteLock rw = new ReentrantReadWriteLock(); + private ReentrantReadWriteLock.ReadLock r = rw.readLock(); + private ReentrantReadWriteLock.WriteLock w = rw.writeLock(); + + public DataContainer(Object data) { + this.data = data; + } + + public Object read() { + log.debug("获取读锁"); + r.lock(); + try { + log.debug("读取"); + Thread.sleep(1000); + return data; + } catch (InterruptedException e) { + throw new RuntimeException(e); + } finally { + log.debug("释放读锁"); + r.unlock(); + } + } + + public void write(Object o) { + log.debug("获取写锁"); + w.lock(); + try { + log.debug("写入"); + Thread.sleep(1000); + this.data = o; + } catch (InterruptedException e) { + throw new RuntimeException(e); + } finally { + log.debug("释放写锁"); + w.unlock(); + } + } +} \ No newline at end of file diff --git a/src/main/java/com/zerroi/charpter08/TestSchedule.java b/src/main/java/com/zerroi/charpter08/TestSchedule.java new file mode 100644 index 0000000..10703aa --- /dev/null +++ b/src/main/java/com/zerroi/charpter08/TestSchedule.java @@ -0,0 +1,29 @@ +package com.zerroi.charpter08; + +import lombok.extern.slf4j.Slf4j; + +import java.time.DayOfWeek; +import java.time.Duration; +import java.time.LocalDateTime; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; + +@Slf4j +public class TestSchedule { + public static void main(String[] args) { + ScheduledExecutorService pool = Executors.newScheduledThreadPool(1); + LocalDateTime now = LocalDateTime.now(); + LocalDateTime time = now.withHour(14).withMinute(36).withSecond(10).withNano(0).with(DayOfWeek.SUNDAY); + if (now.isAfter(time)) { + time = time.plusWeeks(1L); + } +// 当前时间与周四时间差值 + long initialDelay = Duration.between(now, time).toMillis(); +// 每周间隔 + long period = 7 * 100 * 60 * 24 * 60; + pool.scheduleAtFixedRate(() -> { + log.debug("每周四18:00:08"); + }, initialDelay, period, TimeUnit.MILLISECONDS); + } +} diff --git a/src/main/java/com/zerroi/charpter08/TestShutdown.java b/src/main/java/com/zerroi/charpter08/TestShutdown.java new file mode 100644 index 0000000..fdbc95c --- /dev/null +++ b/src/main/java/com/zerroi/charpter08/TestShutdown.java @@ -0,0 +1,50 @@ +package com.zerroi.charpter08; + +import lombok.extern.slf4j.Slf4j; + +import java.util.List; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; +import java.util.concurrent.TimeUnit; + +@Slf4j +public class TestShutdown { + public static void main(String[] args) { + ExecutorService pool = Executors.newFixedThreadPool(2); + Future result1 = pool.submit(() -> { + log.debug("task1 Running"); + Thread.sleep(1000); + log.debug("FINISHED 1"); + return "task1 ok!!!"; + }); + + Future result2 = pool.submit(() -> { + log.debug("task2 Running"); + Thread.sleep(1000); + log.debug("FINISHED 2"); + return "task2 ok!!!"; + }); + + Future result3 = pool.submit(() -> { + log.debug("task3 Running"); + Thread.sleep(1000); + log.debug("FINISHED 3"); + return "task3 ok!!!"; + }); + + /*pool.shutdown(); + try { + pool.awaitTermination(3, TimeUnit.SECONDS); + } catch (InterruptedException e) { + throw new RuntimeException(e); + }*/ + log.debug("SHUTDOWN NOW!"); + List list = pool.shutdownNow(); + list.forEach(Runnable::run); + + log.debug("OTHER"); + + } + +} diff --git a/src/main/java/com/zerroi/charpter08/TestSubmit.java b/src/main/java/com/zerroi/charpter08/TestSubmit.java new file mode 100644 index 0000000..812ab75 --- /dev/null +++ b/src/main/java/com/zerroi/charpter08/TestSubmit.java @@ -0,0 +1,71 @@ +package com.zerroi.charpter08; + +import lombok.extern.slf4j.Slf4j; + +import java.util.Arrays; +import java.util.List; +import java.util.concurrent.*; + +@Slf4j +public class TestSubmit { + public static void main(String[] args) throws ExecutionException, InterruptedException { + ExecutorService pool = Executors.newFixedThreadPool(1); + String s = pool.invokeAny(Arrays.asList( + () -> { + log.debug("BEGIN 111"); + Thread.sleep(1000); + log.debug("END"); + return "1"; + }, + () -> { + log.debug("BEGIN 2222"); + Thread.sleep(500); + log.debug("END"); + return "2"; + }, + () -> { + log.debug("BEGIN 3333"); + Thread.sleep(2000); + return "3"; + } + )); + log.debug("{}", s); + } + + private static void invokeAll(ExecutorService pool) throws InterruptedException { + List> futures = pool.invokeAll(Arrays.asList( + () -> { + log.debug("begin"); + Thread.sleep(1000); + return "1"; + }, + () -> { + log.debug("begin"); + Thread.sleep(500); + return "2"; + }, + () -> { + log.debug("begin"); + Thread.sleep(2000); + return "3"; + } + )); + futures.forEach(f -> { + try { + log.debug("{}", f.get()); + } catch (InterruptedException | ExecutionException e) { + throw new RuntimeException(e); + } + }); + } + + private static void extracted(ExecutorService executorService) throws InterruptedException, ExecutionException { + Future result = executorService.submit(() -> { + log.debug("Running"); + Thread.sleep(1000); + return "ok!!!"; + }); + String res = result.get(); + log.debug("res:{}", res); + } +} diff --git a/src/main/java/com/zerroi/charpter08/TestThreadPoolExecutor.java b/src/main/java/com/zerroi/charpter08/TestThreadPoolExecutor.java new file mode 100644 index 0000000..bba0dcb --- /dev/null +++ b/src/main/java/com/zerroi/charpter08/TestThreadPoolExecutor.java @@ -0,0 +1,25 @@ +package com.zerroi.charpter08; + +import lombok.extern.slf4j.Slf4j; + +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.ThreadFactory; +import java.util.concurrent.atomic.AtomicInteger; + +@Slf4j +public class TestThreadPoolExecutor { + public static void main(String[] args) { + ExecutorService executorService = Executors.newFixedThreadPool(2, new ThreadFactory() { + private AtomicInteger atomicInteger = new AtomicInteger(1); + @Override + public Thread newThread(Runnable r) { + return new Thread(r, "mypool_t" + atomicInteger.getAndAdd(1)); + } + }); + log.debug("teststst"); + executorService.execute(() -> System.out.println(1)); + executorService.execute(() -> System.out.println(2)); + executorService.execute(() -> System.out.println(3)); + } +} diff --git a/src/main/java/com/zerroi/charpter08/TestTimer.java b/src/main/java/com/zerroi/charpter08/TestTimer.java new file mode 100644 index 0000000..84ad970 --- /dev/null +++ b/src/main/java/com/zerroi/charpter08/TestTimer.java @@ -0,0 +1,61 @@ +package com.zerroi.charpter08; + +import lombok.extern.slf4j.Slf4j; + +import java.util.Timer; +import java.util.TimerTask; +import java.util.concurrent.*; + +@Slf4j +public class TestTimer { + public static void main(String[] args) { + ExecutorService pool = Executors.newFixedThreadPool(1); + Future future = pool.submit(() -> { + log.debug("START.."); + int i = 1 / 0; + return true; + }); + try { + Boolean res = future.get(); + log.debug("RES:{}", res); + } catch (InterruptedException | ExecutionException e) { + throw new RuntimeException(e); + } + } + + private static void withfix(ScheduledExecutorService pool) { + pool.scheduleWithFixedDelay(() -> { + log.debug("RUNNING...."); + try { + Thread.sleep(2000); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + }, 1, 1, TimeUnit.SECONDS); + } + + private static void extracted1(ScheduledExecutorService pool) { + pool.scheduleAtFixedRate(() -> { + log.debug("RUNNING...."); + try { + Thread.sleep(500); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + }, 1, 1, TimeUnit.SECONDS); + } + + private static void extracted(ScheduledExecutorService pool) { + pool.schedule(() -> { + log.debug("TASK 1"); + try { + Thread.sleep(2000); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + }, 1, TimeUnit.SECONDS); + + + pool.schedule(() -> {log.debug("TASK 2");}, 1, TimeUnit.SECONDS); + } +} diff --git a/src/main/java/com/zerroi/pattern/RunSequentially.java b/src/main/java/com/zerroi/pattern/RunSequentially.java new file mode 100644 index 0000000..7166c27 --- /dev/null +++ b/src/main/java/com/zerroi/pattern/RunSequentially.java @@ -0,0 +1,34 @@ +package com.zerroi.pattern; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j(topic = "c.RunSequentially") +public class RunSequentially { + static final Object lock = new Object(); + static boolean t2Ran = false; + public static void main(String[] args) { + Thread t1 = new Thread(() -> { + synchronized (lock) { + while (!t2Ran) { + try { + lock.wait(); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + } + } + log.debug("t1"); + }, "t1"); + + Thread t2 = new Thread(() -> { + synchronized (lock) { + log.debug("t2"); + t2Ran = true; + lock.notify(); + } + }, "t2"); + + t1.start(); + t2.start(); + } +} diff --git a/src/main/java/com/zerroi/pattern/RunSequentially2.java b/src/main/java/com/zerroi/pattern/RunSequentially2.java new file mode 100644 index 0000000..fcdf39a --- /dev/null +++ b/src/main/java/com/zerroi/pattern/RunSequentially2.java @@ -0,0 +1,17 @@ +package com.zerroi.pattern; + +import java.util.concurrent.locks.LockSupport; + +public class RunSequentially2 { + public static void main(String[] args) { + Thread t1 = new Thread(() -> { + LockSupport.park(); + System.out.println("t1"); + }, "t1"); + + Thread t2 = new Thread(() -> { + System.out.println("t2"); + LockSupport.unpark(t1); + }, "t2"); + } +} diff --git a/src/main/java/com/zerroi/pattern/RunSequentially3.java b/src/main/java/com/zerroi/pattern/RunSequentially3.java new file mode 100644 index 0000000..5c1f650 --- /dev/null +++ b/src/main/java/com/zerroi/pattern/RunSequentially3.java @@ -0,0 +1,71 @@ +package com.zerroi.pattern; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j(topic = "c.RunSequentially3") +public class RunSequentially3 { + private static Object lock = new Object(); + private static int count = 0; + public static void main(String[] args) { + Thread t1 = new Thread(() -> { + for (int i = 0; i < 5; i++) { + synchronized (lock) { + while (count % 3 != 0) { + try { + lock.wait(); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + } + log.debug("a"); + count++; + lock.notifyAll(); + } + } + }, "t1"); + + Thread t2 = new Thread(() -> { + for (int i = 0; i < 5; i++) { + synchronized (lock) { + while (count % 3 != 1) { + try { + lock.wait(); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + } + log.debug("b"); + count++; + lock.notifyAll(); + } + } + }, "t2"); + + Thread t3 = new Thread(() -> { + for (int i = 0; i < 5; i++) { + synchronized (lock) { + while (count % 3 != 2) { + try { + lock.wait(); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + } + log.debug("c"); + count++; + lock.notifyAll(); + } + } + }, "t3"); + + t1.start(); + t2.start(); + t3.start(); + } +} + +/* +a 1 +b 2 +c 3 +* */ diff --git a/src/main/java/com/zerroi/pattern/RunSequentially4.java b/src/main/java/com/zerroi/pattern/RunSequentially4.java new file mode 100644 index 0000000..c6f8270 --- /dev/null +++ b/src/main/java/com/zerroi/pattern/RunSequentially4.java @@ -0,0 +1,65 @@ +package com.zerroi.pattern; + +import java.util.concurrent.locks.Condition; +import java.util.concurrent.locks.ReentrantLock; + +public class RunSequentially4 { + public static void main(String[] args) throws InterruptedException { + AwaitSignal awaitSignal = new AwaitSignal(5); + Condition condition1 = awaitSignal.newCondition(); + Condition condition2 = awaitSignal.newCondition(); + Condition condition3 = awaitSignal.newCondition(); + new Thread(() -> { + try { + awaitSignal.print("a", condition1, condition2); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + }).start(); + new Thread(() -> { + try { + awaitSignal.print("b", condition2, condition3); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + }).start(); + + new Thread(() -> { + try { + awaitSignal.print("c", condition3, condition1); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + }).start(); + + Thread.sleep(1000); + awaitSignal.lock(); + try { + System.out.println("开始。。。。"); + condition1.signal(); + } finally { + awaitSignal.unlock(); + } + } +} + +class AwaitSignal extends ReentrantLock { + private int loop; + + public AwaitSignal(int loop) { + this.loop = loop; + } + + public void print(String s, Condition cur, Condition next) throws InterruptedException { + for (int i = 0; i < loop; i++) { + lock(); + try { + cur.await(); + System.out.println(s); + next.signal(); + } finally { + unlock(); + } + } + } +} diff --git a/src/main/java/com/zerroi/pattern/RunSequentially5.java b/src/main/java/com/zerroi/pattern/RunSequentially5.java new file mode 100644 index 0000000..39a2494 --- /dev/null +++ b/src/main/java/com/zerroi/pattern/RunSequentially5.java @@ -0,0 +1,43 @@ +package com.zerroi.pattern; + +import java.util.concurrent.locks.LockSupport; + +public class RunSequentially5 { + static Thread t1; + static Thread t2; + static Thread t3; + public static void main(String[] args) { + ParkUnpark parkUnpark = new ParkUnpark(5); + t1 = new Thread(() -> { + parkUnpark.print("a", t2); + }, "t1"); + t2 = new Thread(() -> { + parkUnpark.print("b", t3); + }, "t2"); + t3 = new Thread(() -> { + parkUnpark.print("c", t1); + }, "t3"); + + t1.start(); + t2.start(); + t3.start(); + + LockSupport.unpark(t1); + } +} + +class ParkUnpark { + private int loop; + + public ParkUnpark(int loop) { + this.loop = loop; + } + + public void print(String s, Thread next) { + for (int i = 0; i < loop; i++) { + LockSupport.park(); + System.out.println(s); + LockSupport.unpark(next); + } + } +} diff --git a/src/main/java/com/zerroi/pattern/Test.java b/src/main/java/com/zerroi/pattern/Test.java new file mode 100644 index 0000000..497cf8a --- /dev/null +++ b/src/main/java/com/zerroi/pattern/Test.java @@ -0,0 +1,11 @@ +package com.zerroi.pattern; + +import java.util.ArrayList; +import java.util.List; + +public class Test { + public static void main(String[] args) { + List list = new ArrayList<>(); + list.add(1); + } +} diff --git a/src/main/java/com/zerroi/pattern/TestStarvation.java b/src/main/java/com/zerroi/pattern/TestStarvation.java new file mode 100644 index 0000000..17bf8ef --- /dev/null +++ b/src/main/java/com/zerroi/pattern/TestStarvation.java @@ -0,0 +1,50 @@ +package com.zerroi.pattern; + +import lombok.extern.slf4j.Slf4j; + +import java.util.Arrays; +import java.util.List; +import java.util.Random; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; + +@Slf4j +public class TestStarvation { + static final List MENU = Arrays.asList("地三鲜", "宫保鸡丁", "辣子鸡丁", "烤鸡翅"); + static Random RANDOM = new Random(); + + static String cooking() { + return MENU.get(RANDOM.nextInt(MENU.size())); + } + + public static void main(String[] args) { + ExecutorService waiterPool = Executors.newFixedThreadPool(1); + ExecutorService cookerPool = Executors.newFixedThreadPool(1); + waiterPool.execute(() -> { + log.debug("处理点餐..."); + Future f = cookerPool.submit(() -> { + log.debug("做菜"); + return cooking(); + }); + try { + log.debug("上菜: {}", f.get()); + } catch (InterruptedException | ExecutionException e) { + e.printStackTrace(); + } + }); + waiterPool.execute(() -> { + log.debug("处理点餐..."); + Future f = cookerPool.submit(() -> { + log.debug("做菜"); + return cooking(); + }); + try { + log.debug("上菜: {}", f.get()); + } catch (InterruptedException | ExecutionException e) { + e.printStackTrace(); + } + }); + } +} \ No newline at end of file diff --git a/src/main/java/com/zerroi/test/OverallPlanning.java b/src/main/java/com/zerroi/test/OverallPlanning.java new file mode 100644 index 0000000..a61e3ac --- /dev/null +++ b/src/main/java/com/zerroi/test/OverallPlanning.java @@ -0,0 +1,49 @@ +package com.zerroi.test; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j(topic = "c.OverallPlanning") +public class OverallPlanning { + public static void main(String[] args) { + Thread t1 = new Thread(new Runnable() { + @Override + public void run() { + log.debug("洗水壶"); + sleep(1); + log.debug("烧开水"); + sleep(15); + } + }, "t1"); + + Thread t2 = new Thread(new Runnable() { + @Override + public void run() { + log.debug("洗茶壶"); + sleep(1); + log.debug("洗茶杯"); + sleep(2); + log.debug("拿茶叶"); + sleep(1); + + try { + t1.join(); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + log.debug("泡茶"); + } + }, "t2"); + + + t1.start(); + t2.start(); + } + + private static void sleep(int time) { + try { + Thread.sleep(time); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + } +} diff --git a/src/main/java/com/zerroi/test/PhilosopherDinning.java b/src/main/java/com/zerroi/test/PhilosopherDinning.java new file mode 100644 index 0000000..0cfee74 --- /dev/null +++ b/src/main/java/com/zerroi/test/PhilosopherDinning.java @@ -0,0 +1,66 @@ +package com.zerroi.test; + +import lombok.extern.slf4j.Slf4j; + +public class PhilosopherDinning { + public static void main(String[] args) { + Chopstick c1 = new Chopstick("1"); + Chopstick c2 = new Chopstick("2"); + Chopstick c3 = new Chopstick("3"); + Chopstick c4 = new Chopstick("4"); + Chopstick c5 = new Chopstick("5"); + new Philosopher("苏格拉底", c1, c2).start(); + new Philosopher("柏拉图", c2, c3).start(); + new Philosopher("亚里士多德", c3, c4).start(); + new Philosopher("赫拉克利特", c4, c5).start(); + new Philosopher("阿基米德", c1, c5).start(); + } +} + + +@Slf4j(topic = "c.Philosopher") +class Philosopher extends Thread{ + Chopstick left; + Chopstick right; + + public Philosopher(String name, Chopstick left, Chopstick right) { + super(name); + this.left = left; + this.right = right; + } + + @Override + public void run() { + while (true) { + synchronized (left) { + synchronized (right) { + eat(); + } + } + } + } + + private void eat() { + log.debug("eat....."); + try { +// 思考过程 + sleep(50); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + } +} +class Chopstick { + private String name; + + @Override + public String toString() { + return "Chopstick{" + + "name='" + name + '\'' + + '}'; + } + + public Chopstick(String name) { + this.name = name; + } +} diff --git a/src/main/java/com/zerroi/test/PhilosopherDinning2.java b/src/main/java/com/zerroi/test/PhilosopherDinning2.java new file mode 100644 index 0000000..4d9ec72 --- /dev/null +++ b/src/main/java/com/zerroi/test/PhilosopherDinning2.java @@ -0,0 +1,76 @@ +package com.zerroi.test; + +import lombok.extern.slf4j.Slf4j; + +import java.util.concurrent.locks.ReentrantLock; + +public class PhilosopherDinning2 { + public static void main(String[] args) { + Chopstick2 c1 = new Chopstick2("1"); + Chopstick2 c2 = new Chopstick2("2"); + Chopstick2 c3 = new Chopstick2("3"); + Chopstick2 c4 = new Chopstick2("4"); + Chopstick2 c5 = new Chopstick2("5"); + new Philosopher2("苏格拉底", c1, c2).start(); + new Philosopher2("柏拉图", c2, c3).start(); + new Philosopher2("亚里士多德", c3, c4).start(); + new Philosopher2("赫拉克利特", c4, c5).start(); + new Philosopher2("阿基米德", c5, c1).start(); + } +} + + +@Slf4j(topic = "c.Philosopher2") +class Philosopher2 extends Thread{ + Chopstick2 left; + Chopstick2 right; + + public Philosopher2(String name, Chopstick2 left, Chopstick2 right) { + super(name); + this.left = left; + this.right = right; + } + + @Override + public void run() { + while (true) { + if (left.tryLock()) { + try { + if (right.tryLock()) { + try { + eat(); + } finally { + right.unlock(); + } + } + } finally { + left.unlock(); + } + } + } + } + + private void eat() { + log.debug("eat....."); + try { +// 思考过程 + sleep(500); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + } +} +class Chopstick2 extends ReentrantLock { + private String name; + + @Override + public String toString() { + return "Chopstick{" + + "name='" + name + '\'' + + '}'; + } + + public Chopstick2(String name) { + this.name = name; + } +} diff --git a/src/main/java/com/zerroi/test/ReentrantLockTest.java b/src/main/java/com/zerroi/test/ReentrantLockTest.java new file mode 100644 index 0000000..77a5bdf --- /dev/null +++ b/src/main/java/com/zerroi/test/ReentrantLockTest.java @@ -0,0 +1,39 @@ +package com.zerroi.test; + +import lombok.extern.slf4j.Slf4j; + +import java.util.concurrent.locks.ReentrantLock; + +@Slf4j(topic = "c.ReentrantLockTest") +public class ReentrantLockTest { + static ReentrantLock lock = new ReentrantLock(); + public static void main(String[] args) { + lock.lock(); + + try { + log.debug("enter main"); + m1(); + m2(); + } finally { + lock.unlock(); + } + } + + public static void m1() { + lock.lock(); + try { + log.debug("enter m1"); + } finally { + lock.unlock(); + } + } + + public static void m2() { + lock.lock(); + try { + log.debug("enter m2"); + } finally { + lock.unlock(); + } + } +} diff --git a/src/main/java/com/zerroi/test/ReentrantLockTest2.java b/src/main/java/com/zerroi/test/ReentrantLockTest2.java new file mode 100644 index 0000000..b646581 --- /dev/null +++ b/src/main/java/com/zerroi/test/ReentrantLockTest2.java @@ -0,0 +1,41 @@ +package com.zerroi.test; + +import lombok.extern.slf4j.Slf4j; + +import java.util.concurrent.locks.ReentrantLock; + +@Slf4j(topic = "c.ReentrantLockTest2") +public class ReentrantLockTest2 { + static ReentrantLock lock = new ReentrantLock(); + public static void main(String[] args) { + Thread t1 = new Thread(() -> { + try { +// 如果没有竞争,此方法就会获取lock对象锁 +// 如果有竞争,进入阻塞队列,可以被其他线程interrupt方法打断 + log.debug("尝试获取锁"); + lock.lock(); + } catch (Exception e) { + e.printStackTrace(); + log.debug("没有获取到锁,返回"); + return; + } + try { + log.debug("获取到锁"); + }finally { + lock.unlock(); + } + }, "t1"); + + lock.lock(); + t1.start(); + + try { + Thread.sleep(1000); + log.debug("打断t1"); + t1.interrupt(); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + } + +} diff --git a/src/main/java/com/zerroi/test/ReentrantLockTest3.java b/src/main/java/com/zerroi/test/ReentrantLockTest3.java new file mode 100644 index 0000000..932f8ac --- /dev/null +++ b/src/main/java/com/zerroi/test/ReentrantLockTest3.java @@ -0,0 +1,38 @@ +package com.zerroi.test; + +import lombok.extern.slf4j.Slf4j; + +import java.util.concurrent.TimeUnit; +import java.util.concurrent.locks.ReentrantLock; + +@Slf4j(topic = "c.ReentrantLockTest3") +public class ReentrantLockTest3 { + static ReentrantLock lock = new ReentrantLock(); + public static void main(String[] args) { + Thread t1 = new Thread(() -> { +// 尝试获取锁 + log.debug("尝试获取锁"); + try { + if (!lock.tryLock(1, TimeUnit.SECONDS)) { + log.debug("获取不到锁"); + return; + } + } catch (InterruptedException e) { + e.printStackTrace(); + log.debug("获取不到锁"); + return; + } + + try { + log.debug("获得到锁"); + } finally { + lock.unlock(); + } + }, "t1"); + + log.debug("获得到锁"); + lock.lock(); + t1.start(); + } + +} diff --git a/src/main/java/com/zerroi/test/ReentrantLockTest4.java b/src/main/java/com/zerroi/test/ReentrantLockTest4.java new file mode 100644 index 0000000..758ce7e --- /dev/null +++ b/src/main/java/com/zerroi/test/ReentrantLockTest4.java @@ -0,0 +1,31 @@ +package com.zerroi.test; + +import lombok.extern.slf4j.Slf4j; + +import java.util.concurrent.locks.Condition; +import java.util.concurrent.locks.ReentrantLock; + +@Slf4j(topic = "c.ReentrantLockTest") +public class ReentrantLockTest4 { + static ReentrantLock lock = new ReentrantLock(); + public static void main(String[] args) { +// 创建一个新的条件变量(休息室) + Condition condition1 = lock.newCondition(); + Condition condition2 = lock.newCondition(); + + lock.lock(); +// 进入休息室等待 + try { + condition1.await(); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } finally { + lock.unlock(); + } + +// 叫醒condition1中的某一个线程 + condition1.signal(); +// 叫醒condition1中的所有线程 + condition1.signalAll(); + } +} diff --git a/src/main/java/com/zerroi/test/Test12.java b/src/main/java/com/zerroi/test/Test12.java new file mode 100644 index 0000000..0d93388 --- /dev/null +++ b/src/main/java/com/zerroi/test/Test12.java @@ -0,0 +1,24 @@ +package com.zerroi.test; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j(topic = "c.Test12") +public class Test12 { + public static void main(String[] args) throws InterruptedException { + Thread t1 = new Thread(new Runnable() { + @Override + public void run() { + while (true) { + if (Thread.currentThread().isInterrupted()) { + break; + } + } + } + }, "t1"); + + t1.start(); + Thread.sleep(1000); + log.debug("interrupt"); + t1.interrupt(); + } +} diff --git a/src/main/java/com/zerroi/test/Test13.java b/src/main/java/com/zerroi/test/Test13.java new file mode 100644 index 0000000..8346f5f --- /dev/null +++ b/src/main/java/com/zerroi/test/Test13.java @@ -0,0 +1,28 @@ +package com.zerroi.test; + +import lombok.extern.slf4j.Slf4j; + +import java.util.concurrent.locks.LockSupport; + +import static java.lang.Thread.sleep; + +@Slf4j(topic = "c.Test13") +public class Test13 { + public static void main(String[] args) throws InterruptedException { + test3(); + } + + private static void test3() throws InterruptedException { + Thread t1 = new Thread(() -> { + log.debug("park..."); + LockSupport.park(); + log.debug("unpark..."); + log.debug("打断状态:{}", Thread.currentThread().isInterrupted()); + LockSupport.park(); + log.debug("unpark..."); + }, "t1"); + t1.start(); + sleep(500); + t1.interrupt(); + } +} diff --git a/src/main/java/com/zerroi/test/Test14.java b/src/main/java/com/zerroi/test/Test14.java new file mode 100644 index 0000000..5137479 --- /dev/null +++ b/src/main/java/com/zerroi/test/Test14.java @@ -0,0 +1,100 @@ +package com.zerroi.test; + +import lombok.Getter; +import lombok.extern.slf4j.Slf4j; + +import java.util.Hashtable; +import java.util.Map; +import java.util.Set; + +public class Test14 { + public static void main(String[] args) { + + } +} + +@Slf4j(topic = "c.Resident") +class Resident extends Thread{ + @Override + public void run() { + GuardedObject guardedObject = MailBoxes.createGuardedObject(); + log.debug("开始收信id:{}", guardedObject.getId()); + Object mail = guardedObject.get(5000L); + log.debug("收到信id:{},内容:{}", guardedObject.getId(), mail); + } +} + +@Slf4j(topic = "c.Postman") +class Postman extends Thread { + private int mailId; + private String mail; + public Postman(int mailId, String mail) { + this.mailId = mailId; + this.mail =mail; + } + @Override + public void run() { + GuardedObject guardedObject = MailBoxes.getGuardedObject(mailId); + guardedObject.complete(guardedObject); + } +} + +class MailBoxes { + private static int id = 1; + private static Map map = new Hashtable<>(); + private static synchronized int generateId() { + return id++; + } + + public static GuardedObject createGuardedObject() { + GuardedObject guardedObject = new GuardedObject(generateId()); + map.put(guardedObject.getId(), guardedObject); + return guardedObject; + } + + public Set getIds() { + return map.keySet(); + } + + public static GuardedObject getGuardedObject(int id) { + return map.get(id); + } +} + +@Slf4j(topic = "c.GuardedObject") +class GuardedObject { + @Getter + private int id; + + private Object response; + + public GuardedObject(int id) { + this.id = id; + } + + public Object get(Long timeout) { + synchronized (this) { + long begin = System.currentTimeMillis(); + long passedTime = 0; + while (response == null) { + long waitTime = timeout - passedTime; + if (timeout - passedTime <= 0) { + break; + } + try { + this.wait(waitTime); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + passedTime = System.currentTimeMillis() - begin; + log.debug("timePassed: {}, object is null {}", + passedTime, response == null); + } + } + return response; + } + + public void complete(GuardedObject guardedObject) { + + } +} diff --git a/src/main/java/com/zerroi/test/Test15.java b/src/main/java/com/zerroi/test/Test15.java new file mode 100644 index 0000000..fa6f2c2 --- /dev/null +++ b/src/main/java/com/zerroi/test/Test15.java @@ -0,0 +1,103 @@ +package com.zerroi.test; + +import lombok.Data; +import lombok.extern.slf4j.Slf4j; + +import java.util.LinkedList; + +public class Test15 { + public static void main(String[] args) throws InterruptedException { + MessageQueue messageQueue = new MessageQueue(2); + for (int i = 0; i < 3; i++) { + int id = i; + new Thread(() -> { + messageQueue.put(new Message(id, "值" + id)); + }, "producer" + i).start(); + } + + + + new Thread(()-> { + while (true) { + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + Message message = messageQueue.get(); + } + + }, "consumer").start(); + } + + +} + +@Slf4j(topic = "c.MessageQueue") +class MessageQueue { +// 消息的队列集合 + private LinkedList list = new LinkedList<>(); +// 消息的容量 + private int capacity; + + public MessageQueue(int capacity) { + this.capacity = capacity; + } + + // 获取消息 + public Message get() { +// 检查队列是否为空, + synchronized (list) { + while (list.isEmpty()) { + try { + log.debug("队列为空,消费者线程等待"); + list.wait(); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + } +// 从队列头部获取消息返回 + Message message = list.removeFirst(); + log.debug("消费者消费了一个消息:{}", message); + list.notifyAll(); + return message; + } + } +// 存入消息 + public void put(Message message) { + synchronized (list) { +// 检查队列是否已满 + while (list.size() == capacity) { + log.debug("队列已满,生产者线程等待"); + try { + list.wait(); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + } + list.addLast(message); + log.debug("生产者生产了一个消息:{}", message); + list.notifyAll(); + } + } +} + +@Data +class Message { + private int id; + private Object value; + + public Message(int id, Object value) { + this.id = id; + this.value = value; + } + + @Override + public String toString() { + return "Message{" + + "id=" + id + + ", value=" + value + + '}'; + } + +} \ No newline at end of file diff --git a/src/main/java/com/zerroi/test/Test16.java b/src/main/java/com/zerroi/test/Test16.java new file mode 100644 index 0000000..7b7efbf --- /dev/null +++ b/src/main/java/com/zerroi/test/Test16.java @@ -0,0 +1,43 @@ +package com.zerroi.test; + +import lombok.extern.slf4j.Slf4j; + +import static java.lang.Thread.sleep; + +@Slf4j(topic = "c.Test16") +public class Test16 { + public static void main(String[] args) { + Object A = new Object(); + Object B = new Object(); + Thread t1 = new Thread(() -> { + synchronized (A) { + log.debug("lock A"); + try { + sleep(1000); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + synchronized (B) { + log.debug("lock B"); + log.debug("操作..."); + } + } + }, "t1"); + Thread t2 = new Thread(() -> { + synchronized (B) { + log.debug("lock B"); + try { + sleep(500); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + synchronized (A) { + log.debug("lock A"); + log.debug("操作..."); + } + } + }, "t2"); + t1.start(); + t2.start(); + } +} diff --git a/src/main/java/com/zerroi/test/Test17.java b/src/main/java/com/zerroi/test/Test17.java new file mode 100644 index 0000000..7ca65c2 --- /dev/null +++ b/src/main/java/com/zerroi/test/Test17.java @@ -0,0 +1,46 @@ +package com.zerroi.test; + +import java.util.concurrent.locks.Condition; +import java.util.concurrent.locks.ReentrantLock; + +public class Test17 { + public static void main(String[] args) { + ReentrantLock lock = new ReentrantLock(); + Condition condition = lock.newCondition(); + +// 等待线程 + Runnable waitingTask = () -> { + lock.lock(); + try { + System.out.println("Waiting thread is waiting..."); + condition.await(); // 等待条件变量 + System.out.println("Waiting thread is awake!"); + } catch (InterruptedException e) { + e.printStackTrace(); + } finally { + lock.unlock(); + } + }; + +// 通知线程 + Runnable notifyingTask = () -> { + lock.lock(); + try { + Thread.sleep(2000); // 模拟一些操作 + System.out.println("Notifying thread is notifying..."); + condition.signal(); // 唤醒等待线程 + } catch (InterruptedException e) { + e.printStackTrace(); + } finally { + lock.unlock(); + } + }; + +// 创建线程并启动 + Thread waitingThread = new Thread(waitingTask); + Thread notifyingThread = new Thread(notifyingTask); + waitingThread.start(); + notifyingThread.start(); + + } +} diff --git a/src/main/java/com/zerroi/test/Test4.java b/src/main/java/com/zerroi/test/Test4.java new file mode 100644 index 0000000..3e52ddb --- /dev/null +++ b/src/main/java/com/zerroi/test/Test4.java @@ -0,0 +1,18 @@ +package com.zerroi.test; + +public class Test4 { + public static void main(String[] args) { + method1(10); + } + + private static void method1(int i) { + int y = i + 1; + Object m = method2(); + System.out.println("m = " + m); + } + + private static Object method2() { + return new Object(); + } + +} diff --git a/src/main/java/com/zerroi/test/Test5.java b/src/main/java/com/zerroi/test/Test5.java new file mode 100644 index 0000000..769dccf --- /dev/null +++ b/src/main/java/com/zerroi/test/Test5.java @@ -0,0 +1,17 @@ +package com.zerroi.test; + + +public class Test5 { + public static void main(String[] args) { + Thread t1 = new Thread("t1") { + @Override + public void run() { + System.out.println("running"); + } + }; + System.out.println("t1.getState() = " + t1.getState()); + t1.start(); + t1.start(); + System.out.println("t1.getState() = " + t1.getState()); + } +} diff --git a/src/main/java/com/zerroi/test/Test6.java b/src/main/java/com/zerroi/test/Test6.java new file mode 100644 index 0000000..78e6ede --- /dev/null +++ b/src/main/java/com/zerroi/test/Test6.java @@ -0,0 +1,22 @@ +package com.zerroi.test; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j(topic = "c.Test6") +public class Test6 { + public static void main(String[] args) throws InterruptedException { + Thread t1 = new Thread("t1") { + @Override + public void run() { + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + } + }; + t1.start(); + t1.interrupt(); + log.debug("t1 state: {}", t1.getState()); + } +} diff --git a/src/main/java/com/zerroi/test/Test7.java b/src/main/java/com/zerroi/test/Test7.java new file mode 100644 index 0000000..672f771 --- /dev/null +++ b/src/main/java/com/zerroi/test/Test7.java @@ -0,0 +1,28 @@ +package com.zerroi.test; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j(topic = "c.Test7") +public class Test7 { + public static void main(String[] args) { + Runnable task1 = () -> { + int count = 0; + for (; ; ) { + System.out.println("---->1 " + count++); + } + }; + Runnable task2 = () -> { + int count = 0; + for (; ; ) { +// Thread.yield(); + System.out.println(" ---->2 " + count++); + } + }; + Thread t1 = new Thread(task1, "t1"); + Thread t2 = new Thread(task2, "t2"); + t1.setPriority(Thread.MIN_PRIORITY); + t2.setPriority(Thread.MAX_PRIORITY); + t1.start(); + t2.start(); + } +} diff --git a/src/main/java/com/zerroi/test/Test8.java b/src/main/java/com/zerroi/test/Test8.java new file mode 100644 index 0000000..1bdeafc --- /dev/null +++ b/src/main/java/com/zerroi/test/Test8.java @@ -0,0 +1,31 @@ +package com.zerroi.test; + +import lombok.extern.slf4j.Slf4j; + +import static java.lang.Thread.sleep; + +@Slf4j(topic = "c.Test8") +public class Test8 { + static int r = 0; + public static void main(String[] args) throws InterruptedException { + test1(); + } + private static void test1() throws InterruptedException { + log.debug("开始"); + Thread t1 = new Thread(() -> { + log.debug("开始"); + try { + sleep(1); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + log.debug("结束"); + r = 10; +// log.debug("结果为:{}", r); + }); + t1.start(); + t1.join(); + log.debug("结果为:{}", r); + log.debug("结束"); + } +} diff --git a/src/main/java/com/zerroi/test/Test9.java b/src/main/java/com/zerroi/test/Test9.java new file mode 100644 index 0000000..041604e --- /dev/null +++ b/src/main/java/com/zerroi/test/Test9.java @@ -0,0 +1,26 @@ +package com.zerroi.test; + +public class Test9 { + public static void main(String[] args) throws InterruptedException { + Thread t1 = new Thread(() -> { + + }, "t1"); + } + + private static void extracted() throws InterruptedException { + Thread thread = new Thread(() -> { + try { + System.out.println("Sleeping for 5 seconds..."); + Thread.sleep(5000); + System.out.println("Done sleeping."); + } catch (InterruptedException e) { + e.printStackTrace(); + + } + }); + thread.start(); + Thread.sleep(2000); // Wait for the thread to start sleeping. + thread.interrupt(); // Interrupt the thread. + System.out.println("thread.isInterrupted() = " + thread.isInterrupted()); + } +} \ No newline at end of file diff --git a/src/main/java/com/zerroi/test/TestBiased.java b/src/main/java/com/zerroi/test/TestBiased.java new file mode 100644 index 0000000..0502709 --- /dev/null +++ b/src/main/java/com/zerroi/test/TestBiased.java @@ -0,0 +1,28 @@ +package com.zerroi.test; + + +import lombok.extern.slf4j.Slf4j; +import org.openjdk.jol.info.ClassLayout; + +@Slf4j(topic = "c.TestBiased") +public class TestBiased { + public static void main(String[] args) throws InterruptedException { + Dog dog = new Dog(); + int i = dog.hashCode(); // 会禁用偏向锁 + + String s = ClassLayout.parseInstance(dog).toPrintable(); + log.debug(s); + System.out.println("--------------------------------"); + + synchronized (dog) { + log.debug(ClassLayout.parseInstance(dog).toPrintable()); + } + System.out.println("--------------------------------"); + + log.debug(ClassLayout.parseInstance(new Dog()).toPrintable()); + } +} + +class Dog { + +} diff --git a/src/main/java/com/zerroi/test/TestBiased2.java b/src/main/java/com/zerroi/test/TestBiased2.java new file mode 100644 index 0000000..64b6cb3 --- /dev/null +++ b/src/main/java/com/zerroi/test/TestBiased2.java @@ -0,0 +1,46 @@ +package com.zerroi.test; + + +import lombok.extern.slf4j.Slf4j; +import org.openjdk.jol.info.ClassLayout; + +@Slf4j(topic = "c.TestBiased") +public class TestBiased2 { + public static void main(String[] args) throws InterruptedException { + Cat cat = new Cat(); + new Thread(() -> { + log.debug(ClassLayout.parseInstance(cat).toPrintable()); + System.out.println("--------------------------------"); + synchronized (cat) { + log.debug(ClassLayout.parseInstance(cat).toPrintable()); + } + System.out.println("--------------------------------"); + log.debug(ClassLayout.parseInstance(new Dog()).toPrintable()); + + synchronized (TestBiased2.class) { + TestBiased2.class.notify(); + } + }, "t1").start(); + System.out.println("--------------------------------"); + new Thread(() -> { + synchronized (TestBiased2.class) { + try { + TestBiased2.class.wait(); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + } + log.debug(ClassLayout.parseInstance(cat).toPrintable()); + System.out.println("--------------------------------"); + synchronized (cat) { + log.debug(ClassLayout.parseInstance(cat).toPrintable()); + } + System.out.println("--------------------------------"); + log.debug(ClassLayout.parseInstance(new Dog()).toPrintable()); + }, "t2").start(); + } +} + +class Cat { + +} diff --git a/src/main/java/com/zerroi/test/TestBiased3.java b/src/main/java/com/zerroi/test/TestBiased3.java new file mode 100644 index 0000000..ae42015 --- /dev/null +++ b/src/main/java/com/zerroi/test/TestBiased3.java @@ -0,0 +1,45 @@ +package com.zerroi.test; + +import lombok.extern.slf4j.Slf4j; +import org.openjdk.jol.info.ClassLayout; + +import java.util.Vector; + +@Slf4j(topic = "c.TestBiased3") +public class TestBiased3 { + public static void main(String[] args) { + Vector list = new Vector<>(); + Thread t1 = new Thread(() -> { + for (int i = 0; i < 30; i++) { + Dog d = new Dog(); + list.add(d); + synchronized (d) { + log.debug(i + "\t" + ClassLayout.parseInstance(d).toPrintable()); + } + } + synchronized (list) { + list.notify(); + } + }, "t1"); + t1.start(); + Thread t2 = new Thread(() -> { + synchronized (list) { + try { + list.wait(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + log.debug("===============> "); + for (int i = 0; i < 30; i++) { + Dog d = list.get(i); + log.debug(i + "\t" + ClassLayout.parseInstance(d).toPrintable()); + synchronized (d) { + log.debug(i + "\t" + ClassLayout.parseInstance(d).toPrintable()); + } + log.debug(i + "\t" + ClassLayout.parseInstance(d).toPrintable()); + } + }, "t2"); + t2.start(); + } +} diff --git a/src/main/java/com/zerroi/test/TestFrames.java b/src/main/java/com/zerroi/test/TestFrames.java new file mode 100644 index 0000000..a29d597 --- /dev/null +++ b/src/main/java/com/zerroi/test/TestFrames.java @@ -0,0 +1,26 @@ +package com.zerroi.test; + +public class TestFrames { + public static void main(String[] args) { + Thread t1 = new Thread(){ + @Override + public void run() { + method1(20); + } + }; + t1.setName("t1"); + t1.start(); + t1.isInterrupted(); + method1(10); + } + + private static void method1(int i) { + int y = i + 1; + Object m = method2(); + System.out.println("m = " + m); + } + + private static Object method2() { + return new Object(); + } +} diff --git a/src/main/java/com/zerroi/test/TestJoin.java b/src/main/java/com/zerroi/test/TestJoin.java new file mode 100644 index 0000000..ffacfee --- /dev/null +++ b/src/main/java/com/zerroi/test/TestJoin.java @@ -0,0 +1,41 @@ +package com.zerroi.test; + +import lombok.extern.slf4j.Slf4j; + +import static java.lang.Thread.sleep; + +@Slf4j(topic = "c.TestJoin") +public class TestJoin { + static int r1 = 0; + static int r2 = 0; + + public static void main(String[] args) throws InterruptedException { + test2(); + } + + private static void test2() throws InterruptedException { + Thread t1 = new Thread(() -> { + try { + sleep(1); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + r1 = 10; + }); + Thread t2 = new Thread(() -> { + try { + sleep(2); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + r2 = 20; + }); + long start = System.currentTimeMillis(); + t1.start(); + t2.start(); + t1.join(); + t2.join(); + long end = System.currentTimeMillis(); + log.debug("r1: {} r2: {} cost: {}", r1, r2, end - start); + } +} diff --git a/src/main/java/com/zerroi/test/TestWaitAndNotify.java b/src/main/java/com/zerroi/test/TestWaitAndNotify.java new file mode 100644 index 0000000..c47c5fa --- /dev/null +++ b/src/main/java/com/zerroi/test/TestWaitAndNotify.java @@ -0,0 +1,10 @@ +package com.zerroi.test; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j(topic = "c.TestWaitAndNotify") +public class TestWaitAndNotify { + public static void main(String[] args) { + + } +} diff --git a/src/main/java/com/zerroi/test/TestWaitNotify.java b/src/main/java/com/zerroi/test/TestWaitNotify.java new file mode 100644 index 0000000..6aac5ee --- /dev/null +++ b/src/main/java/com/zerroi/test/TestWaitNotify.java @@ -0,0 +1,39 @@ +package com.zerroi.test; + +import lombok.extern.slf4j.Slf4j; + +import static java.lang.Thread.sleep; + +@Slf4j(topic = "c.TestWaitNotify") +public class TestWaitNotify { + final static Object obj = new Object(); + public static void main(String[] args) throws InterruptedException { + new Thread(() -> { + synchronized (obj) { + log.debug("执行...."); + try { + obj.wait(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + log.debug("其它代码...."); // 断点 + } + },"t1").start(); + new Thread(() -> { + synchronized (obj) { + log.debug("执行...."); + try { + obj.wait(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + log.debug("其它代码...."); // 断点 + } + },"t2").start(); + sleep(500L); + log.debug("唤醒 obj 上其它线程"); + synchronized (obj) { + obj.notifyAll(); // 唤醒obj上所有等待线程 断点 + } + } +} diff --git a/src/main/java/com/zerroi/test/TwoPhaseCommit.java b/src/main/java/com/zerroi/test/TwoPhaseCommit.java new file mode 100644 index 0000000..98313fb --- /dev/null +++ b/src/main/java/com/zerroi/test/TwoPhaseCommit.java @@ -0,0 +1,43 @@ +package com.zerroi.test; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j(topic = "c.TwoPhaseCommit") +public class TwoPhaseCommit { + public static void main(String[] args) throws InterruptedException { + TwoPhase twoPhase = new TwoPhase(); + twoPhase.start(); + Thread.sleep(3500); + twoPhase.stop(); + } +} + +@Slf4j(topic = "c.TwoPhaseCommit") +class TwoPhase { + private Thread monitor; +// 启动监控线程 + public void start() { + monitor = new Thread(() -> { + while (true) { +// 拿到当前线程 + Thread currentThread = Thread.currentThread(); + if (currentThread.isInterrupted()) { + log.debug("料理后事"); + break; + } + try { + Thread.sleep(1000); + log.debug("执行监控记录"); + } catch (InterruptedException e) { + log.error(String.valueOf(e)); +// currentThread.interrupt(); + } + } + }); + monitor.start(); + } +// 终止监控线程 + public void stop() { + monitor.interrupt(); + } +} diff --git a/src/main/java/com/zerroi/test/test3.java b/src/main/java/com/zerroi/test/test3.java new file mode 100644 index 0000000..690312e --- /dev/null +++ b/src/main/java/com/zerroi/test/test3.java @@ -0,0 +1,20 @@ +package com.zerroi.test; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j(topic = "c.TestMultiThread") +public class test3 { + public static void main(String[] args) { + new Thread(() -> { + while (true) { + log.debug("running"); + } + }, "t1").start(); + + new Thread(() -> { + while (true) { + log.debug("running"); + } + }, "t2").start(); + } +} diff --git a/src/main/resources/logback.xml b/src/main/resources/logback.xml new file mode 100644 index 0000000..62b4647 --- /dev/null +++ b/src/main/resources/logback.xml @@ -0,0 +1,36 @@ + + + + + + + %highlight(%d{HH:mm:ss.SSS} [%thread]) [%-5level] %logger{36} - %msg%n + + + + + + + + + + + + + + + threadColor + DEBUG + + Thread-1 + TRACE + + + + + + + + + + diff --git a/tmp/1.txt b/tmp/1.txt new file mode 100644 index 0000000..b4b44b6 --- /dev/null +++ b/tmp/1.txt @@ -0,0 +1,200 @@ +l +d +u +d +k +y +i +o +x +l +t +r +x +o +v +p +j +e +g +k +t +l +i +h +i +p +k +z +k +p +l +n +s +m +c +i +l +u +e +c +p +n +q +t +e +v +x +l +c +f +l +l +y +d +s +d +n +w +d +v +b +i +m +x +o +f +a +p +y +m +b +d +t +g +q +f +b +u +k +m +m +k +v +q +e +w +r +j +r +i +k +x +t +j +w +d +c +z +b +e +k +o +b +a +o +y +e +c +f +o +w +n +n +f +d +m +e +x +h +d +b +a +f +j +g +t +a +k +e +l +e +w +q +i +h +j +m +y +x +w +r +b +b +f +p +q +s +g +o +b +b +h +i +j +d +k +u +v +w +p +g +n +u +k +n +i +x +s +g +m +n +f +u +t +z +d +q +k +n +g +x +o +t +r +m +x +x +w +m +e +n +i +s +w +m +q +k +q +a +h \ No newline at end of file diff --git a/tmp/10.txt b/tmp/10.txt new file mode 100644 index 0000000..95ee0d7 --- /dev/null +++ b/tmp/10.txt @@ -0,0 +1,200 @@ +d +s +g +o +v +x +i +i +e +t +r +w +d +c +d +c +m +q +v +a +q +w +p +n +r +f +b +v +e +n +s +q +p +p +q +j +g +h +u +m +a +x +f +l +x +m +a +j +n +w +z +y +u +w +e +c +k +p +h +q +j +f +r +y +r +l +l +y +e +g +w +j +o +w +n +p +l +n +s +v +x +e +y +i +j +e +w +v +d +n +p +q +d +u +v +z +h +x +w +e +i +p +y +w +j +m +k +g +c +x +i +p +o +i +s +t +v +x +c +s +b +o +s +p +q +t +b +y +g +g +s +q +c +t +d +u +p +z +u +m +o +c +e +f +l +g +x +z +t +c +y +l +l +k +c +n +p +i +k +r +q +h +o +x +j +t +z +e +x +e +t +g +p +s +d +p +n +i +b +u +q +m +h +m +c +s +s +r +g +h +i +e +e +a +a +r +u +z +o +g \ No newline at end of file diff --git a/tmp/11.txt b/tmp/11.txt new file mode 100644 index 0000000..50a7fe9 --- /dev/null +++ b/tmp/11.txt @@ -0,0 +1,200 @@ +o +z +t +c +k +a +k +g +x +j +d +q +e +z +y +d +g +o +j +q +z +e +v +h +r +j +q +w +g +j +q +k +f +q +h +l +y +f +p +p +k +c +y +v +a +k +n +e +c +y +i +q +q +u +x +a +p +p +q +b +f +b +j +g +h +x +z +b +i +f +p +n +t +c +c +f +d +a +d +b +l +y +d +q +g +x +m +u +x +q +x +m +j +v +q +f +h +b +j +g +u +b +e +g +i +z +r +p +q +k +u +j +p +y +o +v +m +t +o +g +a +y +j +v +j +w +a +l +k +g +w +c +r +m +r +q +r +g +o +t +n +m +e +r +p +b +e +g +z +s +k +g +p +i +o +m +a +u +h +r +u +w +q +k +a +c +z +e +h +t +o +n +s +r +a +z +l +k +s +i +t +l +v +x +y +m +d +l +x +w +i +i +z +b +y +j +h +u +u +s \ No newline at end of file diff --git a/tmp/12.txt b/tmp/12.txt new file mode 100644 index 0000000..56a66b9 --- /dev/null +++ b/tmp/12.txt @@ -0,0 +1,200 @@ +d +a +j +c +x +x +u +i +t +h +a +r +n +m +c +j +w +y +n +h +r +v +y +h +v +h +w +o +x +u +y +y +n +m +p +r +l +k +l +i +m +c +k +j +m +p +k +z +j +u +u +e +f +n +s +b +a +u +y +i +c +t +y +x +d +h +p +s +b +x +o +w +a +e +o +m +r +k +t +q +j +b +s +c +p +v +x +p +o +b +i +z +w +i +a +q +z +q +b +l +c +c +r +x +h +j +u +d +w +i +u +l +k +x +v +a +v +t +x +m +n +p +z +b +a +u +f +w +o +l +k +n +o +a +r +e +x +u +c +s +s +n +x +e +g +j +l +o +m +r +g +f +e +g +h +z +y +w +h +m +l +l +b +g +c +o +s +t +x +e +w +k +y +y +a +r +u +j +o +p +k +c +h +u +y +y +o +y +i +t +o +n +x +t +d +r +a +n +w +t \ No newline at end of file diff --git a/tmp/13.txt b/tmp/13.txt new file mode 100644 index 0000000..c7083ed --- /dev/null +++ b/tmp/13.txt @@ -0,0 +1,200 @@ +r +w +o +k +e +g +e +w +q +w +p +l +j +v +g +y +f +x +x +o +a +w +o +y +p +k +s +y +r +o +v +c +u +n +i +y +p +u +i +g +n +o +w +s +f +d +n +m +m +m +h +i +k +j +d +p +s +r +f +n +y +j +h +n +v +m +x +n +q +c +y +b +y +q +v +u +i +a +u +d +k +w +b +o +f +v +s +k +t +r +j +w +b +u +e +r +a +p +r +a +y +k +j +i +g +e +v +c +n +z +o +n +y +p +a +f +p +q +u +v +f +f +k +c +k +k +d +w +h +a +e +k +r +e +r +c +n +m +n +w +b +m +w +g +x +r +u +x +e +o +a +t +n +g +n +y +j +n +k +w +j +f +r +w +q +s +a +z +a +c +y +d +p +u +c +z +o +u +r +v +q +d +g +s +o +w +x +a +e +d +j +n +w +u +u +e +l +v +t +d \ No newline at end of file diff --git a/tmp/14.txt b/tmp/14.txt new file mode 100644 index 0000000..431b2f3 --- /dev/null +++ b/tmp/14.txt @@ -0,0 +1,200 @@ +q +m +a +u +e +o +z +y +q +e +d +p +y +x +k +t +x +s +s +l +i +o +z +o +j +k +z +m +h +r +w +c +h +l +t +z +p +d +r +l +u +f +n +w +z +v +z +g +r +r +i +e +e +o +q +g +j +r +h +m +r +u +p +v +v +a +c +t +t +t +l +k +w +p +o +c +h +g +g +f +x +b +h +p +l +d +j +y +o +t +r +e +g +a +e +l +b +z +l +f +s +y +n +i +p +b +f +i +m +f +u +x +r +u +h +h +v +s +i +g +o +u +h +q +q +d +h +c +y +g +w +y +q +v +d +n +c +b +c +a +r +w +g +v +z +d +o +c +s +j +m +a +p +a +o +h +j +q +f +h +c +q +g +n +j +b +s +s +e +t +l +d +p +j +x +d +t +e +p +p +i +s +n +r +x +u +b +e +j +b +s +u +a +x +y +i +q +z +z +x \ No newline at end of file diff --git a/tmp/15.txt b/tmp/15.txt new file mode 100644 index 0000000..426199a --- /dev/null +++ b/tmp/15.txt @@ -0,0 +1,200 @@ +s +c +p +m +g +d +u +v +l +l +w +m +k +d +f +a +c +g +v +d +y +q +k +u +g +b +u +h +m +s +t +g +b +y +e +b +y +y +y +e +a +q +x +d +h +q +e +o +q +p +h +b +m +b +s +n +n +r +j +t +v +p +a +l +s +z +x +x +c +k +t +u +k +n +s +t +v +h +d +j +o +i +p +v +p +q +t +v +p +f +i +n +s +l +h +h +j +h +y +g +v +j +m +f +x +f +o +f +m +p +i +x +d +f +c +f +e +i +f +x +o +d +q +p +w +b +g +y +l +p +v +y +f +i +o +b +f +a +l +r +v +w +k +m +e +z +w +x +i +s +m +n +k +z +s +h +c +b +m +z +q +u +g +l +f +i +f +s +h +h +j +p +t +n +u +e +a +j +v +k +i +e +a +o +a +t +z +n +m +g +c +n +j +e +v +p +s +e +p +q \ No newline at end of file diff --git a/tmp/16.txt b/tmp/16.txt new file mode 100644 index 0000000..a2e6e70 --- /dev/null +++ b/tmp/16.txt @@ -0,0 +1,200 @@ +a +x +v +d +n +s +s +s +g +t +p +t +x +u +d +b +f +z +h +e +k +e +q +r +h +r +l +l +q +r +f +t +j +t +p +k +b +y +j +t +v +j +y +y +t +x +d +s +v +b +l +a +s +d +r +d +b +e +w +l +n +c +e +v +j +b +e +w +a +s +k +j +z +e +a +e +l +r +k +v +v +g +f +p +q +x +q +q +q +b +l +j +i +w +f +u +a +c +e +y +f +e +j +e +c +b +h +f +c +u +w +p +a +b +r +h +w +j +v +m +b +a +l +x +i +t +x +g +t +i +e +u +y +l +x +w +u +e +w +z +g +p +a +q +c +q +l +d +o +m +z +r +e +s +l +j +m +o +s +d +f +z +h +i +v +u +z +o +e +l +p +x +u +k +p +a +z +u +q +r +s +p +g +z +r +b +u +t +a +a +j +n +p +s +o +q +b +h +q +o \ No newline at end of file diff --git a/tmp/17.txt b/tmp/17.txt new file mode 100644 index 0000000..8007552 --- /dev/null +++ b/tmp/17.txt @@ -0,0 +1,200 @@ +m +c +i +b +s +s +k +v +n +e +i +x +v +a +r +g +g +v +d +h +z +r +b +y +q +g +u +x +o +x +x +o +b +f +v +c +v +b +a +w +a +l +z +u +v +l +m +t +j +a +f +r +i +r +y +i +r +d +r +e +x +k +s +r +c +j +o +g +f +e +m +g +w +l +e +h +y +b +g +z +n +b +v +w +v +b +z +j +r +z +v +n +y +p +d +k +u +b +u +p +i +o +b +b +d +o +p +y +r +u +u +t +e +v +d +r +c +c +u +t +l +v +d +v +w +c +e +m +o +i +c +n +f +i +k +m +r +q +w +h +r +v +o +z +w +x +a +k +y +u +l +v +q +a +k +x +s +e +p +f +j +o +a +p +c +u +z +h +s +o +e +j +m +q +m +w +m +x +n +n +q +h +k +l +j +j +l +h +a +y +i +y +p +m +i +d +q +j +m +x \ No newline at end of file diff --git a/tmp/18.txt b/tmp/18.txt new file mode 100644 index 0000000..1fd22c0 --- /dev/null +++ b/tmp/18.txt @@ -0,0 +1,200 @@ +y +t +f +h +t +o +j +o +b +v +k +g +b +w +t +i +r +y +x +v +x +m +s +c +l +u +m +v +q +r +h +h +j +p +k +x +a +t +r +n +m +k +a +x +y +p +y +o +p +z +b +f +q +l +w +x +t +c +x +r +r +r +z +s +l +y +d +f +q +b +m +i +z +u +m +o +f +k +l +g +y +r +f +l +q +s +f +w +v +i +s +x +n +x +n +h +j +v +y +w +j +m +z +x +b +i +k +z +u +n +u +q +z +s +v +j +p +p +b +p +l +h +q +w +l +n +g +t +z +z +x +w +v +w +l +x +r +s +u +p +f +d +r +q +g +m +v +v +c +b +h +n +w +e +b +f +y +y +i +y +o +h +f +e +z +k +l +o +l +r +b +w +h +l +w +w +a +p +z +i +f +f +i +v +z +x +g +q +t +y +n +b +t +i +d +u +h +q +z +l \ No newline at end of file diff --git a/tmp/19.txt b/tmp/19.txt new file mode 100644 index 0000000..ff8b947 --- /dev/null +++ b/tmp/19.txt @@ -0,0 +1,200 @@ +i +j +u +y +f +l +i +a +y +c +n +y +l +e +k +u +k +e +r +u +u +d +u +f +q +g +c +v +w +n +z +a +f +e +u +n +z +k +j +l +j +z +c +j +r +m +c +d +c +h +h +p +j +g +m +t +t +n +d +r +r +p +a +m +g +y +r +t +w +s +l +m +s +w +a +s +x +t +i +u +s +v +l +w +i +x +f +q +p +x +m +s +l +d +r +v +n +a +d +z +l +p +e +h +k +j +k +z +j +z +g +m +e +k +o +k +m +p +t +w +v +v +q +v +l +y +z +s +m +c +m +e +r +s +z +c +j +f +w +z +b +p +w +s +p +l +u +p +w +k +d +t +z +a +n +g +j +p +v +a +s +c +r +g +a +r +g +i +n +u +r +c +e +i +i +r +j +p +z +y +c +x +r +j +c +i +t +n +j +u +r +u +a +x +g +g +x +w +c +k \ No newline at end of file diff --git a/tmp/2.txt b/tmp/2.txt new file mode 100644 index 0000000..c7e5deb --- /dev/null +++ b/tmp/2.txt @@ -0,0 +1,200 @@ +v +q +l +x +z +p +v +l +h +n +b +q +b +n +x +h +b +s +i +n +f +v +i +a +k +w +d +u +r +d +j +p +t +j +d +u +w +u +k +u +o +n +n +w +d +d +d +h +d +i +o +n +b +c +j +a +l +b +q +i +z +s +r +z +s +z +z +y +o +y +r +g +o +z +k +x +j +o +r +r +m +s +w +p +k +a +m +y +q +g +j +t +h +f +b +q +j +v +r +z +m +f +r +y +k +v +x +m +k +p +e +a +q +a +i +w +e +c +t +y +m +t +g +x +t +a +u +c +d +o +x +n +s +y +b +q +s +v +i +p +u +o +f +l +e +n +n +j +d +x +n +w +d +n +t +p +b +j +f +i +f +d +p +v +f +p +b +u +i +b +l +i +b +f +j +f +a +w +m +s +d +j +h +p +b +b +q +c +u +v +l +k +d +o +f +g +m +z +r +b \ No newline at end of file diff --git a/tmp/20.txt b/tmp/20.txt new file mode 100644 index 0000000..14dca3c --- /dev/null +++ b/tmp/20.txt @@ -0,0 +1,200 @@ +e +x +r +h +g +g +s +v +s +a +g +b +t +d +r +m +x +p +c +k +q +n +d +n +s +r +a +b +g +u +v +t +a +r +z +s +p +g +e +f +j +f +x +p +t +n +t +m +v +h +l +k +t +q +k +x +y +o +k +h +j +h +d +r +x +n +q +l +q +w +l +b +p +z +u +h +n +n +h +w +r +i +m +e +a +t +n +v +d +c +m +l +d +i +y +z +g +m +z +i +g +o +u +k +f +u +h +d +m +x +g +y +t +e +m +n +b +x +m +d +p +z +r +y +w +u +x +s +s +v +o +d +d +e +z +p +t +j +t +d +t +m +a +e +e +l +h +n +m +g +d +z +r +y +o +f +p +a +k +w +m +p +j +l +c +o +u +k +t +c +q +u +d +a +b +o +w +z +z +i +v +f +s +b +h +b +j +o +v +v +h +z +s +p +d +l +n +y +h +e \ No newline at end of file diff --git a/tmp/21.txt b/tmp/21.txt new file mode 100644 index 0000000..6960868 --- /dev/null +++ b/tmp/21.txt @@ -0,0 +1,200 @@ +l +b +k +r +o +h +d +c +f +r +l +j +y +i +i +z +q +o +v +f +h +x +r +c +b +u +j +p +u +z +q +u +a +s +x +w +n +x +y +u +d +z +u +t +u +m +a +m +x +a +n +x +f +s +x +n +m +q +k +n +r +f +t +i +k +m +q +o +l +j +i +s +v +g +x +e +j +x +l +e +j +y +z +d +q +c +g +f +r +s +e +s +p +t +f +p +o +z +j +s +n +j +o +a +m +f +o +t +k +a +w +c +y +p +i +i +t +o +s +c +h +a +m +t +k +y +s +d +v +d +f +b +d +q +m +g +i +t +g +e +t +k +d +h +w +y +p +a +f +c +a +k +r +t +k +u +f +q +h +a +r +c +z +y +t +v +a +j +a +d +g +i +m +p +w +y +c +j +q +c +y +j +e +m +x +b +w +n +x +p +s +d +i +c +g +t +a +d +q +o \ No newline at end of file diff --git a/tmp/22.txt b/tmp/22.txt new file mode 100644 index 0000000..4c619c8 --- /dev/null +++ b/tmp/22.txt @@ -0,0 +1,200 @@ +j +c +b +a +n +c +s +x +b +s +w +h +s +y +i +f +w +t +z +q +l +l +q +b +w +f +s +y +c +e +m +z +c +p +f +m +p +y +g +y +w +u +s +w +k +z +w +n +a +s +q +s +x +d +c +s +i +f +x +z +b +t +i +i +p +l +n +a +c +s +a +o +j +v +n +p +b +f +t +c +y +v +g +t +s +g +s +w +k +q +l +g +g +t +v +a +i +l +b +v +l +c +a +n +n +d +k +t +a +e +h +p +b +q +m +q +c +v +q +u +s +z +m +i +h +c +h +a +l +x +g +x +d +v +c +w +q +l +t +u +q +t +t +b +g +l +b +u +o +z +y +d +f +r +c +f +r +a +i +n +b +n +x +h +w +h +k +a +g +p +h +t +j +o +m +m +y +s +a +d +c +l +f +g +b +a +u +n +x +z +j +j +t +z +s +u +p +f +p +t \ No newline at end of file diff --git a/tmp/23.txt b/tmp/23.txt new file mode 100644 index 0000000..0b1b156 --- /dev/null +++ b/tmp/23.txt @@ -0,0 +1,200 @@ +l +c +k +f +o +i +l +x +o +d +c +z +f +j +y +p +x +l +g +s +s +a +w +c +j +j +f +o +l +r +x +i +o +j +e +w +h +v +s +m +d +k +z +k +y +l +b +u +o +z +s +q +s +n +b +o +u +h +h +p +y +c +n +g +y +j +m +m +y +w +e +o +g +v +a +f +c +n +o +t +r +n +h +d +k +n +r +p +k +n +q +g +o +e +i +e +k +d +v +s +i +o +v +h +f +g +i +m +w +v +h +h +u +t +c +m +b +i +m +v +i +u +p +b +d +z +d +e +x +e +o +a +z +i +n +f +k +s +k +m +j +n +i +x +r +a +w +y +o +b +k +o +n +w +o +f +o +d +v +c +t +t +q +a +l +f +d +i +z +y +i +t +f +n +h +c +j +q +e +e +c +g +i +n +a +x +e +w +x +f +s +y +e +j +n +u +n +y +b +h \ No newline at end of file diff --git a/tmp/24.txt b/tmp/24.txt new file mode 100644 index 0000000..bf7301b --- /dev/null +++ b/tmp/24.txt @@ -0,0 +1,200 @@ +m +d +o +o +y +g +q +a +h +q +a +c +u +s +n +s +y +d +g +c +b +l +o +l +a +o +p +h +c +f +j +q +z +k +q +b +s +d +y +h +i +f +u +v +r +w +x +f +l +n +n +t +c +t +f +h +b +t +w +k +t +w +g +g +p +m +x +l +t +k +j +o +x +t +e +n +u +z +n +u +t +c +c +u +e +q +g +m +o +e +j +i +v +o +y +u +i +d +w +h +n +d +n +d +m +c +r +k +m +o +z +y +c +z +f +f +c +d +c +a +w +z +p +i +r +s +m +q +f +b +s +b +u +s +v +b +n +e +b +j +t +e +p +u +k +m +z +v +n +k +z +f +t +d +i +o +w +w +g +f +q +a +b +l +s +n +d +w +w +h +z +z +o +k +q +e +j +a +q +k +k +w +y +c +x +o +h +m +o +t +m +h +w +h +h +j +y +x +b +r \ No newline at end of file diff --git a/tmp/25.txt b/tmp/25.txt new file mode 100644 index 0000000..bae1795 --- /dev/null +++ b/tmp/25.txt @@ -0,0 +1,200 @@ +t +j +c +x +a +y +y +y +v +x +o +k +i +f +x +n +z +v +h +t +x +r +g +x +o +v +r +g +r +a +h +l +c +u +w +w +p +p +l +h +p +d +x +m +c +d +j +e +f +z +m +d +u +h +g +m +z +k +o +m +o +w +b +v +o +l +o +w +u +h +z +w +z +a +g +d +q +e +a +s +f +k +v +f +z +a +n +a +p +u +z +a +i +v +r +m +r +b +q +q +d +g +a +g +s +d +o +l +k +f +l +z +p +c +v +j +u +e +w +c +s +u +i +l +c +h +b +g +l +h +o +r +t +k +c +v +r +t +r +g +y +h +p +t +a +e +h +v +j +w +p +y +f +l +f +z +p +n +h +e +n +e +s +n +c +t +f +n +c +s +t +y +i +m +b +d +f +m +r +j +y +b +p +b +m +x +h +n +u +k +f +i +p +u +z +b +w +i +q +s \ No newline at end of file diff --git a/tmp/26.txt b/tmp/26.txt new file mode 100644 index 0000000..5f9370d --- /dev/null +++ b/tmp/26.txt @@ -0,0 +1,200 @@ +x +u +b +y +o +r +s +g +z +t +e +c +f +j +z +o +a +t +p +p +d +e +y +u +b +q +c +k +k +m +h +t +q +b +i +b +r +o +z +w +e +k +w +k +o +u +t +m +z +z +v +l +i +z +j +d +p +s +y +i +v +a +j +z +a +h +j +i +r +z +h +h +z +t +k +o +q +l +y +i +a +p +n +b +r +o +w +l +q +l +b +y +z +s +z +j +r +h +q +t +m +g +d +x +f +f +o +o +a +o +u +v +g +d +k +a +i +c +u +b +s +o +k +z +k +h +q +u +l +t +x +c +a +m +e +v +j +q +g +s +y +v +w +c +s +d +x +y +t +n +e +n +i +b +g +y +x +d +q +x +h +h +i +j +q +i +z +s +b +h +b +q +h +p +u +p +f +n +u +s +q +j +g +k +e +v +n +i +s +t +i +c +y +i +h +v +t +c +s +w \ No newline at end of file diff --git a/tmp/3.txt b/tmp/3.txt new file mode 100644 index 0000000..f5ec8dd --- /dev/null +++ b/tmp/3.txt @@ -0,0 +1,200 @@ +m +r +f +g +q +k +w +e +z +l +z +h +u +w +e +m +r +y +y +v +i +t +h +n +j +x +k +n +m +f +t +u +q +s +h +a +t +z +w +g +y +e +f +z +c +i +m +m +b +q +l +f +m +e +h +b +j +m +e +q +p +s +l +o +q +n +g +s +m +a +q +y +n +s +r +b +j +i +l +u +v +e +k +w +u +u +r +g +g +p +j +s +e +l +n +c +k +x +u +l +z +l +e +b +l +g +x +a +y +l +z +s +m +l +k +q +r +d +u +a +k +u +h +u +p +f +t +t +m +q +q +t +b +j +i +k +f +j +f +b +i +o +c +a +b +n +g +b +y +g +a +n +c +d +g +z +p +w +p +h +t +b +b +v +b +c +p +a +n +k +m +s +g +y +e +k +b +b +i +f +f +e +p +j +v +k +e +f +o +x +z +y +a +i +m +e +v +i +p +f \ No newline at end of file diff --git a/tmp/4.txt b/tmp/4.txt new file mode 100644 index 0000000..ebd37fb --- /dev/null +++ b/tmp/4.txt @@ -0,0 +1,200 @@ +v +o +v +y +z +w +j +o +l +m +h +m +n +y +q +i +f +l +f +r +h +b +c +y +e +m +e +r +q +c +w +f +k +o +e +t +o +m +k +d +t +e +c +e +l +c +g +x +t +e +e +a +h +v +b +j +q +w +b +c +k +l +w +f +w +i +r +q +e +h +g +y +l +g +g +b +z +v +l +y +j +v +r +v +y +h +p +s +v +u +x +m +z +u +d +s +z +f +k +r +f +c +a +k +l +r +l +q +h +d +e +s +j +s +x +h +b +x +p +m +f +o +h +t +z +a +b +x +c +r +l +o +t +p +k +r +g +p +a +o +r +c +w +z +i +i +v +a +w +q +i +d +m +l +h +o +v +t +o +r +g +u +x +w +u +q +u +e +n +v +l +m +z +q +c +v +e +t +c +x +m +h +r +b +e +d +h +d +g +u +d +z +v +k +g +d +n +j +v +y \ No newline at end of file diff --git a/tmp/5.txt b/tmp/5.txt new file mode 100644 index 0000000..a779202 --- /dev/null +++ b/tmp/5.txt @@ -0,0 +1,200 @@ +e +n +i +i +s +v +m +v +e +l +x +r +d +h +j +o +a +u +t +m +j +q +z +f +r +r +k +b +t +o +b +w +b +h +u +t +q +c +g +u +k +h +k +x +k +z +c +t +u +s +a +g +y +u +f +o +c +d +k +r +o +l +o +o +g +k +n +h +z +n +t +w +f +r +e +h +h +j +r +x +e +i +p +d +x +k +h +o +a +y +e +c +h +k +f +s +v +k +m +t +x +u +d +o +w +o +k +j +z +m +l +f +f +p +w +w +l +b +m +i +r +q +s +o +j +i +g +j +z +g +s +n +o +u +w +p +f +b +w +o +w +p +m +k +y +x +q +z +s +m +u +f +e +z +p +a +j +l +t +f +w +g +c +d +p +o +r +h +o +r +n +n +f +n +e +c +i +j +m +n +z +h +r +n +h +i +k +v +t +h +b +o +n +j +k +v +r +l +w +o \ No newline at end of file diff --git a/tmp/6.txt b/tmp/6.txt new file mode 100644 index 0000000..d95d447 --- /dev/null +++ b/tmp/6.txt @@ -0,0 +1,200 @@ +q +k +k +x +d +y +p +p +p +d +w +h +c +x +i +d +d +v +b +v +p +n +b +j +g +p +w +t +d +q +o +t +m +o +n +m +g +b +y +y +s +x +s +h +j +e +t +p +w +a +j +a +t +q +z +l +u +v +h +r +d +i +l +v +a +j +r +t +u +d +z +q +e +g +u +s +i +l +m +b +x +g +u +y +h +y +s +u +a +i +f +t +y +u +g +m +t +p +u +b +a +k +v +m +z +m +f +h +l +y +q +q +f +g +z +r +r +k +q +p +h +o +k +a +f +a +t +g +k +m +v +n +l +c +g +l +d +e +m +f +u +j +t +p +n +z +p +q +h +b +e +j +l +w +o +k +p +e +y +a +z +b +v +w +a +g +f +h +s +r +p +s +u +r +a +b +j +a +h +m +a +t +x +e +i +w +i +e +v +g +m +c +d +x +j +n +w +q +s +e \ No newline at end of file diff --git a/tmp/7.txt b/tmp/7.txt new file mode 100644 index 0000000..06e2118 --- /dev/null +++ b/tmp/7.txt @@ -0,0 +1,200 @@ +q +j +z +j +i +x +g +j +z +n +v +y +o +o +k +d +k +q +z +e +x +s +y +m +n +y +h +q +f +b +l +q +y +v +q +h +w +b +s +o +a +w +f +x +c +y +k +f +v +m +t +d +j +f +i +x +q +w +g +z +d +y +q +r +l +m +l +c +m +u +t +j +g +g +s +k +e +j +o +g +p +z +r +s +d +c +j +i +w +i +i +o +l +j +p +e +i +s +c +h +z +c +m +u +j +s +x +p +k +g +z +y +k +q +r +p +y +o +r +v +k +l +x +l +w +x +f +d +b +v +v +j +s +f +u +j +i +f +a +x +t +z +g +l +b +c +b +r +r +e +b +k +v +d +k +x +b +f +n +f +i +s +q +w +t +k +c +v +d +q +f +x +y +v +v +l +w +d +w +o +s +f +j +l +m +a +l +f +c +v +u +o +m +q +e +r +v +z +g +f \ No newline at end of file diff --git a/tmp/8.txt b/tmp/8.txt new file mode 100644 index 0000000..5b822cf --- /dev/null +++ b/tmp/8.txt @@ -0,0 +1,200 @@ +u +o +s +k +m +o +k +j +g +x +g +t +q +l +i +n +x +d +p +b +b +g +c +l +i +q +n +g +o +l +i +v +s +m +p +l +r +k +d +a +z +d +f +f +c +h +z +w +r +v +s +l +o +f +j +j +w +k +u +n +t +e +a +z +g +w +k +i +c +i +s +m +z +n +x +r +s +e +u +d +d +i +b +i +g +l +c +s +s +u +g +a +s +g +e +c +b +x +b +i +d +a +v +m +p +n +k +g +p +v +r +y +a +b +e +h +i +i +t +s +t +g +f +w +y +t +k +j +w +x +u +x +u +y +s +s +b +e +h +t +h +z +u +f +d +w +s +r +p +l +o +a +d +c +d +h +s +m +r +h +s +g +c +t +d +i +z +n +q +d +v +p +y +g +q +w +y +a +w +n +u +w +r +g +t +r +g +h +l +r +t +x +d +b +m +e +h +s +d +n \ No newline at end of file diff --git a/tmp/9.txt b/tmp/9.txt new file mode 100644 index 0000000..3892552 --- /dev/null +++ b/tmp/9.txt @@ -0,0 +1,200 @@ +a +e +t +e +g +j +i +g +t +l +m +w +l +b +j +y +h +e +v +c +t +a +z +d +x +r +w +g +n +c +p +a +g +t +r +n +f +u +q +m +y +r +y +q +h +n +q +l +q +f +i +j +q +l +l +j +s +g +t +s +y +h +e +a +d +i +c +g +l +d +x +v +y +o +a +q +e +c +r +t +t +u +t +d +d +i +x +y +s +c +o +h +f +l +x +v +u +e +r +i +k +v +d +c +a +q +c +c +h +y +i +h +i +k +j +o +k +q +b +a +u +e +w +e +r +y +q +p +v +f +d +v +j +f +j +l +a +e +g +n +c +e +r +d +w +z +d +y +i +p +f +n +z +h +z +w +l +u +c +j +c +v +l +n +n +u +a +n +b +z +n +a +d +v +x +k +c +a +v +n +o +p +t +y +l +e +g +w +v +u +c +w +m +r +m +o +i +v +y +z \ No newline at end of file