diff --git a/.gitignore b/.gitignore index 80b6c36650ad493d5e9d4fa1b3268cb12abaca62..3ba5e2fd043b42aaf3913030c1df2e77dc9bc660 100644 --- a/.gitignore +++ b/.gitignore @@ -1,15 +1,33 @@ +*.DS_Store +/*/*.DS_Store + +/*/bin/ +/*/target/ +/*/build/ +bin/ +target/ +build/ +logs/ + +/*/logs/ +.idea/ +/*/.idea/ +/*/*.iml +*.iml + +/*/*.classpath +*.classpath +/*/.settings/ +/*/*/.settings/ +/*/.project +.project + # Compiled class file *.class # Log file *.log -# BlueJ files -*.ctxt - -# Mobile Tools for Java (J2ME) -.mtj.tmp/ - # Package Files # *.jar *.war @@ -18,8 +36,6 @@ *.zip *.tar.gz *.rar -*.idea -./target -*.iml + # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml hs_err_pid* diff --git a/pom.xml b/pom.xml index 568faf31f72e08022adeb2e8a0860ea45fd02d5c..7d06bec20f2f2b2418436d37286260b2f171d083 100644 --- a/pom.xml +++ b/pom.xml @@ -11,7 +11,7 @@ org.idea - concurrence-programming-lession + juc-programming 1.0-SNAPSHOT diff --git "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21305/Condition\346\241\210\344\276\213/ConditionDemo_1.java" "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/Condition\346\241\210\344\276\213/ConditionDemo_1.java" similarity index 97% rename from "src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21305/Condition\346\241\210\344\276\213/ConditionDemo_1.java" rename to "src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/Condition\346\241\210\344\276\213/ConditionDemo_1.java" index 12e0c4c4dd0627d8fb5276ff472bd8bc67782c3c..a2dfb8dcfdeab4cf396b82e96449939b349749cb 100644 --- "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21305/Condition\346\241\210\344\276\213/ConditionDemo_1.java" +++ "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/Condition\346\241\210\344\276\213/ConditionDemo_1.java" @@ -1,4 +1,4 @@ -package 并发编程05.Condition案例; +package 并发编程.demo.Condition案例; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; diff --git "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/CountDownLatch\346\241\210\344\276\213/CountDownLatchTest.java" "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/CountDownLatch\346\241\210\344\276\213/CountDownLatchTest.java" new file mode 100644 index 0000000000000000000000000000000000000000..cc395e689ee45a8b06aea80f7d88c14414f50872 --- /dev/null +++ "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/CountDownLatch\346\241\210\344\276\213/CountDownLatchTest.java" @@ -0,0 +1,47 @@ +package 并发编程.demo.CountDownLatch案例; + +import java.util.concurrent.CountDownLatch; + +/** + * 场景1 让多个线程等待:模拟并发,让并发线程一起执行 + * + * CountDownLatch应用场景 + * CountDownLatch一般用作多线程倒计时计数器,强制它们等待其他一组(CountDownLatch的初始化决定)任务执行完成。 + * CountDownLatch的两种使用场景: + * 场景1:让多个线程等待 + * 场景2:让单个线程等待。 + * + * CountDownLatch实现原理 + * 底层基于 AbstractQueuedSynchronizer 实现,CountDownLatch 构造函数中指定的count直接赋给AQS的state;每次countDown()则都是release(1)减1,最后减到0时unpark阻塞线程;这一步是由最后一个执行countdown方法的线程执行的。 + * 而调用await()方法时,当前线程就会判断state属性是否为0,如果为0,则继续往下执行,如果不为0,则使当前线程进入等待状态,直到某个线程将state属性置为0,其就会唤醒在await()方法中等待的线程。 + * + * CountDownLatch与Thread.join的区别 + * CountDownLatch的作用就是允许一个或多个线程等待其他线程完成操作,看起来有点类似join() 方法,但其提供了比 join() 更加灵活的API。 + * CountDownLatch可以手动控制在n个线程里调用n次countDown()方法使计数器进行减一操作,也可以在一个线程里调用n次执行减一操作。 + * 而 join() 的实现原理是不停检查join线程是否存活,如果 join 线程存活则让当前线程永远等待。所以两者之间相对来说还是CountDownLatch使用起来较为灵活。 + */ +public class CountDownLatchTest { + + + public static void main(String[] args) throws InterruptedException { + CountDownLatch countDownLatch = new CountDownLatch(1); + System.out.println("比赛开始"); + for (int i = 0; i < 5; i++) { + Thread.sleep(1000); + new Thread(() -> { + try { + String partner = "【" + Thread.currentThread().getName() + "】"; + System.out.println(partner + "准备就绪……"); + //准备完毕……运动员都阻塞在这,等待号令 + countDownLatch.await(); + System.out.println(partner + "开跑!"); + } catch (InterruptedException e) { + e.printStackTrace(); + } + },"运动员" + i+1).start(); + } + + Thread.sleep(2000);// 裁判准备发令 + countDownLatch.countDown();// 发令枪:执行发令 + } +} \ No newline at end of file diff --git "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/CountDownLatch\346\241\210\344\276\213/CountDownLatchTest2.java" "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/CountDownLatch\346\241\210\344\276\213/CountDownLatchTest2.java" new file mode 100644 index 0000000000000000000000000000000000000000..c17c2905cbacecfe96d68d70a27ecfc298d27822 --- /dev/null +++ "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/CountDownLatch\346\241\210\344\276\213/CountDownLatchTest2.java" @@ -0,0 +1,37 @@ +package 并发编程.demo.CountDownLatch案例; + +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.ThreadLocalRandom; + +/** + * 场景2 让单个线程等待:多个线程(任务)完成后,进行汇总合并 + * 一个车能做5个乘客。司机必须等到5个乘客都上车之后才能发车 + * + * 很多时候,我们的并发任务,存在前后依赖关系;比如数据详情页需要同时调用多个接口获取数据,并发请求获取到数据后、需要进行结果合并; + * 或者多个数据操作完成后,需要数据check;这其实都是:在多个线程(任务)完成后,进行汇总合并的场景。 + */ +public class CountDownLatchTest2 { + + public static void main(String[] args) throws Exception { + + // 一个车能做5个乘客。司机必须等到5个乘客都上车之后才能发车 + CountDownLatch countDownLatch = new CountDownLatch(5); + for (int i = 0; i < 5; i++) { + final int index = i+1; + Thread.sleep(1000 + ThreadLocalRandom.current().nextInt(1000)); + new Thread(() -> { + try { + System.out.println("【"+Thread.currentThread().getName()+"】已上车"); + countDownLatch.countDown(); + } catch (Exception e) { + e.printStackTrace(); + } + },"乘客" + index).start(); + } + // 主线程在阻塞,当计数器==0,就唤醒主线程往下执行。 + countDownLatch.await(); + // 即:所有乘客都上车之后才发车 + System.out.println("【发车!】"); + + } +} \ No newline at end of file diff --git "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21310/CyclicBarrier\346\241\210\344\276\213/CyclicBarrierDemo.java" "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/CyclicBarrier\346\241\210\344\276\213/CyclicBarrierDemo.java" similarity index 96% rename from "src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21310/CyclicBarrier\346\241\210\344\276\213/CyclicBarrierDemo.java" rename to "src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/CyclicBarrier\346\241\210\344\276\213/CyclicBarrierDemo.java" index 5c23dead7c2ed61475b42ce56b45b7b50d28f2f8..5a9a521ec50884cdae70c26f5d20fd521b1a6f98 100644 --- "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21310/CyclicBarrier\346\241\210\344\276\213/CyclicBarrierDemo.java" +++ "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/CyclicBarrier\346\241\210\344\276\213/CyclicBarrierDemo.java" @@ -1,4 +1,4 @@ -package 并发编程10.CyclicBarrier案例; +package 并发编程.demo.CyclicBarrier案例; import java.util.ArrayList; import java.util.List; diff --git "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/CyclicBarrier\346\241\210\344\276\213/CyclicBarrierTest1.java" "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/CyclicBarrier\346\241\210\344\276\213/CyclicBarrierTest1.java" new file mode 100644 index 0000000000000000000000000000000000000000..16b1a49e946298816c42bc1ae1e815135db37044 --- /dev/null +++ "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/CyclicBarrier\346\241\210\344\276\213/CyclicBarrierTest1.java" @@ -0,0 +1,60 @@ +package 并发编程.demo.CyclicBarrier案例; + +import java.util.Set; +import java.util.concurrent.*; + +/** + * CyclicBarrier介绍 + * 字面意思回环栅栏,通过它可以实现让一组线程等待至某个状态(屏障点)之后再全部同时执行。叫做回环是因为当所有等待线程都被释放以后,CyclicBarrier可以被重用。 + * + * 构造方法 public CyclicBarrier(int parties) parties表示屏障拦截的线程数量,每个线程调用 await 方法告诉 CyclicBarrier 我已经到达了屏障,然后当前线程被阻塞。 + * 用于在线程到达屏障时,优先执行 barrierAction,方便处理更复杂的业务场景(该线程的执行时机是在到达屏障之后再执行) + * + * CyclicBarrier应用场景: + * CyclicBarrier 可以用于多线程计算数据,最后合并计算结果的场景。 + */ +public class CyclicBarrierTest1 { + + //保存每个学生的平均成绩 + private ConcurrentHashMap map = new ConcurrentHashMap(); + + private ExecutorService threadPool = Executors.newFixedThreadPool(3); + + private CyclicBarrier cb = new CyclicBarrier(3, () -> { + int result = 0; + Set set = map.keySet(); + for (String s : set) { + result += map.get(s); + } + System.out.println("三人平均成绩为:" + (result / 3) + "分"); + }); + + + public void count() { + for (int i = 0; i < 3; i++) { + threadPool.execute(new Runnable() { + + @Override + public void run() { + //获取学生平均成绩 + int score = (int) (Math.random() * 40 + 60); + map.put(Thread.currentThread().getName(), score); + System.out.println(Thread.currentThread().getName() + + "同学的平均成绩为:" + score); + try { + //执行完运行await(),等待所有学生平均成绩都计算完毕 + cb.await(); + } catch (InterruptedException | BrokenBarrierException e) { + e.printStackTrace(); + } + } + + }); + } + } + + public static void main(String[] args) { + CyclicBarrierTest1 cb = new CyclicBarrierTest1(); + cb.count(); + } +} \ No newline at end of file diff --git "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/CyclicBarrier\346\241\210\344\276\213/CyclicBarrierTest2.java" "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/CyclicBarrier\346\241\210\344\276\213/CyclicBarrierTest2.java" new file mode 100644 index 0000000000000000000000000000000000000000..974cdfb47243998771bfcc36b4a3f002cc934e5f --- /dev/null +++ "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/CyclicBarrier\346\241\210\344\276\213/CyclicBarrierTest2.java" @@ -0,0 +1,66 @@ +package 并发编程.demo.CyclicBarrier案例; + +import java.util.concurrent.*; +import java.util.concurrent.atomic.AtomicInteger; + +/** + * 利用CyclicBarrier的计数器能够重置,屏障可以重复使用的特性,可以支持类似“人满发车”的场景(重复) + * 一次性的"人满发车"场景可以使用CountDownLatch 实现 + * + * CyclicBarrier与CountDownLatch的区别 + * CountDownLatch的计数器只能使用一次,而CyclicBarrier的计数器可以使用reset() 方法重置。所以CyclicBarrier能处理更为复杂的业务场景,比如如果计算发生错误,可以重置计数器,并让线程们重新执行一次 + * CyclicBarrier还提供getNumberWaiting(可以获得CyclicBarrier阻塞的线程数量)、isBroken(用来知道阻塞的线程是否被中断)等方法。 + * CountDownLatch会阻塞主线程,CyclicBarrier不会阻塞主线程,只会阻塞子线程。 + * CountDownLatch和CyclicBarrier都能够实现线程之间的等待,只不过它们侧重点不同。CountDownLatch一般用于一个或多个线程,等待其他线程执行完任务后,再执行。CyclicBarrier一般用于一组线程互相等待至某个状态,然后这一组线程再同时执行。 + * CyclicBarrier 还可以提供一个 barrierAction,合并多线程计算结果。 + * CyclicBarrier是通过ReentrantLock的"独占锁"和Conditon来实现一组线程的阻塞唤醒的,而CountDownLatch则是通过AQS的“共享锁”实现 + * + * CyclicBarrier源码分析 + * 关注点: + * 1.一组线程在触发屏障之前互相等待,最后一个线程到达屏障后唤醒逻辑是如何实现的 + * 2.删栏循环使用是如何实现的 + * 3.条件队列到同步队列的转换实现逻辑 + */ +public class CyclicBarrierTest2 { + + public static void main(String[] args) { + + AtomicInteger counter = new AtomicInteger(); + ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor( + 5, 5, 1000, TimeUnit.SECONDS, + new ArrayBlockingQueue<>(100), + (r) -> new Thread(r, counter.addAndGet(1) + " 号 "), + new ThreadPoolExecutor.AbortPolicy()); + + CyclicBarrier cyclicBarrier = new CyclicBarrier(5, + () -> System.out.println("裁判:比赛开始~~")); + + for (int i = 0; i < 10; i++) { + threadPoolExecutor.submit(new Runner(cyclicBarrier)); + } + + } + + static class Runner extends Thread { + private CyclicBarrier cyclicBarrier; + + public Runner(CyclicBarrier cyclicBarrier) { + this.cyclicBarrier = cyclicBarrier; + } + + @Override + public void run() { + try { + int sleepMills = ThreadLocalRandom.current().nextInt(1000); + Thread.sleep(sleepMills); + System.out.println(Thread.currentThread().getName() + " 选手已就位, 准备共用时: " + sleepMills + "ms" + cyclicBarrier.getNumberWaiting()); + cyclicBarrier.await(); + + } catch (InterruptedException e) { + e.printStackTrace(); + } catch (BrokenBarrierException e) { + e.printStackTrace(); + } + } + } +} \ No newline at end of file diff --git "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21310/CyclicBarrier\346\241\210\344\276\213/MultiRequestHandler.java" "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/CyclicBarrier\346\241\210\344\276\213/MultiRequestHandler.java" similarity index 93% rename from "src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21310/CyclicBarrier\346\241\210\344\276\213/MultiRequestHandler.java" rename to "src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/CyclicBarrier\346\241\210\344\276\213/MultiRequestHandler.java" index f969031a06ca63d997d628eee5f1352f9730d3bc..0b91ae9c077ece7550b1b3aae789950ef16538e0 100644 --- "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21310/CyclicBarrier\346\241\210\344\276\213/MultiRequestHandler.java" +++ "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/CyclicBarrier\346\241\210\344\276\213/MultiRequestHandler.java" @@ -1,6 +1,5 @@ -package 并发编程10.CyclicBarrier案例; +package 并发编程.demo.CyclicBarrier案例; -import java.util.concurrent.BrokenBarrierException; import java.util.concurrent.CyclicBarrier; /** diff --git "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21304/ReentrantLock\346\241\210\344\276\213/LockCompareDemo.java" "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/ReentrantLock\346\241\210\344\276\213/LockCompareDemo.java" similarity index 97% rename from "src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21304/ReentrantLock\346\241\210\344\276\213/LockCompareDemo.java" rename to "src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/ReentrantLock\346\241\210\344\276\213/LockCompareDemo.java" index 39a6e366fe666a9c4341d802e68e3187d9877d1b..ba494abdbcea21b166826ae3895f13e786023257 100644 --- "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21304/ReentrantLock\346\241\210\344\276\213/LockCompareDemo.java" +++ "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/ReentrantLock\346\241\210\344\276\213/LockCompareDemo.java" @@ -1,4 +1,4 @@ -package 并发编程04.ReentrantLock案例; +package 并发编程.demo.ReentrantLock案例; import java.util.concurrent.TimeUnit; import java.util.concurrent.locks.ReentrantLock; diff --git "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21310/Semaphore\346\241\210\344\276\213/BlockQueue.java" "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/Semaphore\346\241\210\344\276\213/BlockQueue.java" similarity index 86% rename from "src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21310/Semaphore\346\241\210\344\276\213/BlockQueue.java" rename to "src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/Semaphore\346\241\210\344\276\213/BlockQueue.java" index f5d1bc5c32da8328a92f7763cbd31eed6ba4c5b5..489edc5f18389978690b8af4fe67efeecc7cad79 100644 --- "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21310/Semaphore\346\241\210\344\276\213/BlockQueue.java" +++ "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/Semaphore\346\241\210\344\276\213/BlockQueue.java" @@ -1,4 +1,4 @@ -package 并发编程10.Semaphore案例; +package 并发编程.demo.Semaphore案例; import java.util.ArrayList; import java.util.List; @@ -12,22 +12,19 @@ import java.util.concurrent.TimeUnit; */ public class BlockQueue { - private CountDownLatch countDownLatch = new CountDownLatch(1); + private final Semaphore semaphore; + private final List list; - private Semaphore semaphore; - private List list; - - private int currentIndex = 0; - - private int maxLen; + private final int maxLen; public BlockQueue(int size) { - this.list = new ArrayList(size * 2); + this.list = new ArrayList(size * 2); this.maxLen = size; this.semaphore = new Semaphore(size); } public void add(Integer item) { + int currentIndex = 0; if (currentIndex == maxLen) { throw new IndexOutOfBoundsException("队列存储空间有限,不能再放入新的元素"); } diff --git "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/Semaphore\346\241\210\344\276\213/SemaphoreTest2.java" "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/Semaphore\346\241\210\344\276\213/SemaphoreTest2.java" new file mode 100644 index 0000000000000000000000000000000000000000..a59ee0700bc3f804d4eb33285fd707ddf3a7cf4f --- /dev/null +++ "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/Semaphore\346\241\210\344\276\213/SemaphoreTest2.java" @@ -0,0 +1,82 @@ +package 并发编程.demo.Semaphore案例; + +import java.util.concurrent.LinkedBlockingDeque; +import java.util.concurrent.Semaphore; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; + +/** + * Semaphore,俗称信号量,它是操作系统中PV操作的原语在java的实现,它也是基于AbstractQueuedSynchronizer实现的。 + * Semaphore的功能非常强大,大小为1的信号量就类似于互斥锁,通过同时只能有一个线程获取信号量实现。大小为n(n>0)的信号量可以实现限流的功能,它可以实现只能有n个线程同时获取信号量。 + * + * PV操作是操作系统一种实现进程互斥与同步的有效方法。PV操作与信号量(S)的处理相关,P表示通过的意思,V表示释放的意思。用PV操作来管理共享资源时,首先要确保PV操作自身执行的正确性。 + * P操作的主要动作是: + * ①S减1; + * ②若S减1后仍大于或等于0,则进程继续执行; + * ③若S减1后小于0,则该进程被阻塞后放入等待该信号量的等待队列中,然后转进程调度。 + * V操作的主要动作是: + * ①S加1; + * ②若相加后结果大于0,则进程继续执行; + * ③若相加后结果小于或等于0,则从该信号的等待队列中释放一个等待进程,然后再返回原进程继续执行或转进程调度。 + * + * 应用场景 + * 可以用于做流量控制,特别是公用资源有限的应用场景 + * + * 构造函数入参 + * permits 表示许可证的数量(资源数) + * fair 表示公平性,如果这个设为 true 的话,下次执行的线程会是等待最久的线程 + * + * 常用方法 + * public void acquire() throws InterruptedException ==> 表示阻塞并获取许可 + * public boolean tryAcquire() ==> 方法在没有许可的情况下会立即返回 false,要获取许可的线程不会阻塞 + * public void release() ==> 表示释放许可 + * public int availablePermits() ==> 返回此信号量中当前可用的许可证数。 + * public final int getQueueLength() ==> 返回正在等待获取许可证的线程数。 + * public final boolean hasQueuedThreads() ==> 是否有线程正在等待获取许可证。 + * protected void reducePermits(int reduction) ==> 减少 reduction 个许可证 + * Collection getQueuedThreads() ==> 返回所有等待获取许可证的线程集合 + * + * 建议: 先跟上节课ReentrantLock的源码,再来跟Semaphore的源码 + * 关注点: + * 1. Semaphore的加锁解锁(共享锁)逻辑实现 + * 2. 线程竞争锁失败入队阻塞逻辑和获取锁的线程释放锁唤醒阻塞线程竞争锁的逻辑实现 + * 源码笔记:https://www.processon.com/view/link/61950f6e5653bb30803c5bd2 + */ +public class SemaphoreTest2 { + + /** + * 实现一个同时只能处理5个请求的限流器 + */ + private static Semaphore semaphore = new Semaphore(5); + + /** + * 定义一个线程池 + */ + private static ThreadPoolExecutor executor = new ThreadPoolExecutor(10, 50, 60, TimeUnit.SECONDS, new LinkedBlockingDeque<>(200)); + + /** + * 模拟执行方法 + */ + public static void exec() { + try { + semaphore.acquire(1); + // 模拟真实方法执行 + System.out.println("执行exec方法"); + Thread.sleep(2000); + } catch (Exception e) { + e.printStackTrace(); + } finally { + semaphore.release(1); + } + } + + public static void main(String[] args) throws InterruptedException { + { + for (; ; ) { + Thread.sleep(100); + // 模拟请求以10个/s的速度 + executor.execute(() -> exec()); + } + } + } +} \ No newline at end of file diff --git "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21300/cpu\350\260\203\345\272\246/CpuTaskDemo.java" "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/cpu\350\260\203\345\272\246/CpuTaskDemo.java" similarity index 97% rename from "src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21300/cpu\350\260\203\345\272\246/CpuTaskDemo.java" rename to "src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/cpu\350\260\203\345\272\246/CpuTaskDemo.java" index 4d19200b1abe7e7072a923dd1a2fff40bcf6de47..a254481c57a6d6d31b20ff557f990509a8ff620d 100644 --- "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21300/cpu\350\260\203\345\272\246/CpuTaskDemo.java" +++ "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/cpu\350\260\203\345\272\246/CpuTaskDemo.java" @@ -1,4 +1,4 @@ -package 并发编程00.cpu调度; +package 并发编程.demo.cpu调度; /** * @Author idea diff --git "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21318/forkjoin\344\275\277\347\224\250\346\241\210\344\276\213/ForkJoinFindBigNumberDemo.java" "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/forkjoin\344\275\277\347\224\250\346\241\210\344\276\213/ForkJoinFindBigNumberDemo.java" similarity index 96% rename from "src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21318/forkjoin\344\275\277\347\224\250\346\241\210\344\276\213/ForkJoinFindBigNumberDemo.java" rename to "src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/forkjoin\344\275\277\347\224\250\346\241\210\344\276\213/ForkJoinFindBigNumberDemo.java" index 58b496e6c5f2d6caf70f02c8af42299c20506eb0..a438d4332264ce5556c2761670ab871f84449fb2 100644 --- "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21318/forkjoin\344\275\277\347\224\250\346\241\210\344\276\213/ForkJoinFindBigNumberDemo.java" +++ "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/forkjoin\344\275\277\347\224\250\346\241\210\344\276\213/ForkJoinFindBigNumberDemo.java" @@ -1,4 +1,4 @@ -package 并发编程18.forkjoin使用案例; +package 并发编程.demo.forkjoin使用案例; import java.util.Arrays; import java.util.concurrent.ForkJoinPool; diff --git "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21318/forkjoin\344\275\277\347\224\250\346\241\210\344\276\213/ForkJoinSumDemo.java" "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/forkjoin\344\275\277\347\224\250\346\241\210\344\276\213/ForkJoinSumDemo.java" similarity index 97% rename from "src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21318/forkjoin\344\275\277\347\224\250\346\241\210\344\276\213/ForkJoinSumDemo.java" rename to "src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/forkjoin\344\275\277\347\224\250\346\241\210\344\276\213/ForkJoinSumDemo.java" index c9066c6586c9f304bb33ed138e3b32fdacb71a8d..62c8a0ed1f577aefb09b71d449cc630529b3b010 100644 --- "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21318/forkjoin\344\275\277\347\224\250\346\241\210\344\276\213/ForkJoinSumDemo.java" +++ "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/forkjoin\344\275\277\347\224\250\346\241\210\344\276\213/ForkJoinSumDemo.java" @@ -1,4 +1,4 @@ -package 并发编程18.forkjoin使用案例; +package 并发编程.demo.forkjoin使用案例; import java.util.Random; import java.util.concurrent.ForkJoinPool; diff --git "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/lock_support/AtomicStampedReferenceTest.java" "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/lock_support/AtomicStampedReferenceTest.java" new file mode 100644 index 0000000000000000000000000000000000000000..9cb66b5889bc00c2b0490a077558ba3f833c19ba --- /dev/null +++ "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/lock_support/AtomicStampedReferenceTest.java" @@ -0,0 +1,59 @@ +package 并发编程.demo.lock_support; + +import lombok.extern.slf4j.Slf4j; + +import java.util.concurrent.atomic.AtomicStampedReference; +import java.util.concurrent.locks.LockSupport; + +/** + * 通过 AtomicStampedReference 解决 ABA 问题 + * reference即我们实际存储的变量,stamp是版本,每次修改可以通过+1保证版本唯一性。这样就可以保证每次修改后的版本也会往上递增。 + * + * AtomicMarkableReference 可以理解为上面AtomicStampedReference的简化版,就是不关心修改过几次,仅仅关心是否修改过。 + * 因此变量mark是boolean类型,仅记录值是否有过修改。 + */ +@Slf4j +public class AtomicStampedReferenceTest { + + public static void main(String[] args) { + // 定义AtomicStampedReference Pair.reference值为1, Pair.stamp为1 + AtomicStampedReference atomicStampedReference = new AtomicStampedReference(1, 1); + + new Thread(() -> { + int[] stampHolder = new int[1]; + int value = (int) atomicStampedReference.get(stampHolder); + int stamp = stampHolder[0]; + log.debug("Thread1 read value: " + value + ", stamp: " + stamp); + + // 阻塞1s + LockSupport.parkNanos(1000000000L); + // Thread1通过CAS修改value值为3 + if (atomicStampedReference.compareAndSet(value, 3, stamp, stamp + 1)) { + log.debug("Thread1 update from " + value + " to 3"); + } else { + log.debug("Thread1 update fail!"); + } + }, "Thread1").start(); + + new Thread(() -> { + int[] stampHolder = new int[1]; + int value = (int) atomicStampedReference.get(stampHolder); + int stamp = stampHolder[0]; + log.debug("Thread2 read value: " + value + ", stamp: " + stamp); + // Thread2通过CAS修改value值为2 + if (atomicStampedReference.compareAndSet(value, 2, stamp, stamp + 1)) { + log.debug("Thread2 update from " + value + " to 2"); + + // do something + + value = (int) atomicStampedReference.get(stampHolder); + stamp = stampHolder[0]; + log.debug("Thread2 read value: " + value + ", stamp: " + stamp); + // Thread2通过CAS修改value值为1 + if (atomicStampedReference.compareAndSet(value, 1, stamp, stamp + 1)) { + log.debug("Thread2 update from " + value + " to 1"); + } + } + }, "Thread2").start(); + } +} \ No newline at end of file diff --git "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/lock_support/LockSupportDemo.java" "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/lock_support/LockSupportDemo.java" new file mode 100644 index 0000000000000000000000000000000000000000..f35b3514dfc6f23eed678dfb9419e4c10d696b25 --- /dev/null +++ "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/lock_support/LockSupportDemo.java" @@ -0,0 +1,28 @@ +package 并发编程.demo.lock_support; + +import java.util.concurrent.locks.LockSupport; + +/** + * LockSupport是JDK中用来实现线程阻塞和唤醒的工具,线程调用park则等待“许可”,调用unpark则为指定线程提供“许可”。 + * 使用它可以在任何场合使线程阻塞,可以指定任何线程进行唤醒,并且不用担心阻塞和唤醒操作的顺序,但要注意连续多次唤醒的效果和一次唤醒是一样的。 + */ +public class LockSupportDemo { + + public static void main(String[] args) { + Thread parkThread = new Thread(new ParkThread()); + parkThread.start(); + + System.out.println("唤醒parkThread"); + LockSupport.unpark(parkThread); + } + + static class ParkThread implements Runnable{ + + @Override + public void run() { + System.out.println("ParkThread开始执行"); + LockSupport.park(); + System.out.println("ParkThread执行完成"); + } + } +} \ No newline at end of file diff --git "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/pipe/Piped.java" "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/pipe/Piped.java" new file mode 100644 index 0000000000000000000000000000000000000000..c8541d45e20ebe69c751a6a93269e24f79c7ae2a --- /dev/null +++ "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/pipe/Piped.java" @@ -0,0 +1,51 @@ +package 并发编程.demo.pipe; + +import java.io.IOException; +import java.io.PipedReader; +import java.io.PipedWriter; + +/** + * 管道输入输出流 + * 管道输入/输出流和普通的文件输入/输出流或者网络输入/输出流不同之处在于,它主要用于线程之间的数据传输,而传输的媒介为内存。管道输入/输出流 + * 主要包括了如下4种具体实现:PipedOutputStream、PipedInputStream、PipedReader和PipedWriter,前两种面向字节,而后两种面向字符。 + */ +public class Piped { + + public static void main(String[] args) throws Exception { + PipedWriter out = new PipedWriter(); + PipedReader in = new PipedReader(); + // 将输出流和输入流进行连接,否则在使用时会抛出IOException + out.connect(in); + + Thread printThread = new Thread(new Print(in), "PrintThread"); + + printThread.start(); + int receive = 0; + try { + while ((receive = System.in.read()) != -1) { + out.write(receive); + } + } finally { + out.close(); + } + } + + static class Print implements Runnable { + private PipedReader in; + + public Print(PipedReader in) { + this.in = in; + } + + @Override + public void run() { + int receive = 0; + try { + while ((receive = in.read()) != -1) { + System.out.print((char) receive); + } + } catch (IOException ex) { + } + } + } +} \ No newline at end of file diff --git "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/reentrantReadWriteLock/Cache.java" "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/reentrantReadWriteLock/Cache.java" new file mode 100644 index 0000000000000000000000000000000000000000..5aca0281831c4078074b122ba7d616e4387d8c1c --- /dev/null +++ "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/reentrantReadWriteLock/Cache.java" @@ -0,0 +1,53 @@ +package 并发编程.demo.reentrantReadWriteLock; + +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantReadWriteLock; + +/** + * ReentrantReadWriteLock 读多写少的场景:Cache缓存 + * + * Cache组合一个非线程安全的HashMap作为缓存的实现,同时使用读写锁的读锁和写锁来保证Cache是线程安全的。 + * 在读操作get(String key)方法中,需要获取读锁,这使得并发访问该方法时不会被阻塞。 + * 写操作put(String key,Object value)方法和clear()方法,在更新 HashMap时必须提前获取写锁, + * 当获取写锁后,其他线程对于读锁和写锁的获取均被阻塞,而只有写锁被释放之后,其他读写操作才能继续。 + * Cache使用读写锁提升读操作的并发性,也保证每次写操作对所有的读写操作的可见性,同时简化了编程方式 + */ +public class Cache { + + static Map map = new HashMap(); + static ReentrantReadWriteLock rwl = new ReentrantReadWriteLock(); + static Lock r = rwl.readLock(); + static Lock w = rwl.writeLock(); + + // 获取一个key对应的value + public static final Object get(String key) { + r.lock(); + try { + return map.get(key); + } finally { + r.unlock(); + } + } + + // 设置key对应的value,并返回旧的value + public static final Object put(String key, Object value) { + w.lock(); + try { + return map.put(key, value); + } finally { + w.unlock(); + } + } + + // 清空所有的内容 + public static final void clear() { + w.lock(); + try { + map.clear(); + } finally { + w.unlock(); + } + } +} \ No newline at end of file diff --git "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/reentrantReadWriteLock/LockRelegate.java" "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/reentrantReadWriteLock/LockRelegate.java" new file mode 100644 index 0000000000000000000000000000000000000000..e46f2fb551455a98533174155c7e5893b807c0cc --- /dev/null +++ "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/reentrantReadWriteLock/LockRelegate.java" @@ -0,0 +1,55 @@ +package 并发编程.demo.reentrantReadWriteLock; + +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantReadWriteLock; + +/** + * 锁降级 + * 锁降级指的是写锁降级成为读锁。如果当前线程拥有写锁,然后将其释放,最后再获取读锁,这种分段完成的过程不能称之为锁降级。锁降级是指把持住(当前拥有的)写锁, + * 再获取到读锁,随后释放(先前拥有的)写锁的过程。锁降级可以帮助我们拿到当前线程修改后的结果而不被其他线程所破坏,防止更新丢失。 + * + * 锁降级的使用示例 + * 因为数据不常变化,所以多个线程可以并发地进行数据处理,当数据变更后,如果当前线程感知到数据变化,则进行数据的准备工作,同时其他处理线程被阻塞,直到当前线程完成数据的准备工作。 + * + * 锁降级中读锁的获取是否必要呢?答案是必要的。主要是为了保证数据的可见性,如果当前线程不获取读锁而是直接释放写锁,假设此刻另一个线程(记作线程T)获取了写锁并修改了数据, + * 那么当前线程无法感知线程T的数据更新。如果当前线程获取读锁,即遵循锁降级的步骤,则线程T将会被阻塞,直到当前线程使用数据并释放读锁之后,线程T才能获取写锁进行数据更新。 + * + * ReentrantReadWriteLock 不支持锁升级(把持读锁、获取写锁,最后释放读锁的过程)。目的也是保证数据可见性,如果读锁已被多个线程获取,其中任意线程成功获取了写锁并更新了数据, + * 则其更新对其他获取到读锁的线程是不可见的。 + * + * 思考: + * 1. 读写锁是怎样实现分别记录读写状态的? + * 2. 写锁是怎样获取和释放的? + * 3. 读锁是怎样获取和释放的? + */ +public class LockRelegate { + private final ReentrantReadWriteLock rwl = new ReentrantReadWriteLock(); + private final Lock readLock = rwl.readLock(); + private final Lock writeLock = rwl.writeLock(); + private volatile boolean update = false; + + public void processData() { + readLock.lock(); + if (!update) { + // 必须先释放读锁 + readLock.unlock(); + // 锁降级从写锁获取到开始 + writeLock.lock(); + try { + if (!update) { + // TODO 准备数据的流程(略) + update = true; + } + readLock.lock(); + } finally { + writeLock.unlock(); + } + // 锁降级完成,写锁降级为读锁 + } + try { + //TODO 使用数据的流程(略) + } finally { + readLock.unlock(); + } + } +} diff --git "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/reentrantReadWriteLock/ReentrantReadWriteLockDemo.java" "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/reentrantReadWriteLock/ReentrantReadWriteLockDemo.java" new file mode 100644 index 0000000000000000000000000000000000000000..0b965723be332cc983d98872b3db54eaaa908e67 --- /dev/null +++ "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/reentrantReadWriteLock/ReentrantReadWriteLockDemo.java" @@ -0,0 +1,61 @@ +package 并发编程.demo.reentrantReadWriteLock; + +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReadWriteLock; +import java.util.concurrent.locks.ReentrantReadWriteLock; + +/** + * 读写锁介绍 + * 现实中有这样一种场景:对共享资源有读和写的操作,且写操作没有读操作那么频繁(读多写少)。在没有写操作的时候,多个线程同时读一个资源没有任何问题,所以应该允许多个线程同时读取共享资源(读读可以并发);但是如果一个线程想去写这些共享资源,就不应该允许其他线程对该资源进行读和写操作了(读写,写读,写写互斥)。在读多于写的情况下,读写锁能够提供比排它锁更好的并发性和吞吐量。 + * 针对这种场景,JAVA的并发包提供了读写锁ReentrantReadWriteLock,它内部,维护了一对相关的锁,一个用于只读操作,称为读锁;一个用于写入操作,称为写锁,描述如下: + * + * 线程进入读锁的前提条件: + * 没有其他线程的写锁 + * 没有写请求或者有写请求,但调用线程和持有锁的线程是同一个。 + * + * 线程进入写锁的前提条件: + * 没有其他线程的读锁 + * 没有其他线程的写锁 + * + * 而读写锁有以下三个重要的特性: + * 公平选择性:支持非公平(默认)和公平的锁获取方式,吞吐量还是非公平优于公平。 + * 可重入:读锁和写锁都支持线程重入。以读写线程为例:读线程获取读锁后,能够再次获取读锁。写线程在获取写锁之后能够再次获取写锁,同时也可以获取读锁。 + * 锁降级:遵循获取写锁、再获取读锁最后释放写锁的次序,写锁能够降级成为读锁。 + * + * ReentrantReadWriteLock是可重入的读写锁实现类。在它内部,维护了一对相关的锁,一个用于只读操作,另一个用于写入操作。只要没有 Writer 线程, + * 读锁可以由多个 Reader 线程同时持有。也就是说,写锁是独占的,读锁是共享的。 + * + * 注意事项 + * 1、读锁不支持条件变量 + * 2、重入时升级不支持:持有读锁的情况下去获取写锁,会导致获取永久等待 + * 3、重入时支持降级: 持有写锁的情况下可以去获取读锁 + * + * ReentrantReadWriteLock 适合读多写少的场景 + */ +public class ReentrantReadWriteLockDemo { + private ReadWriteLock readWriteLock = new ReentrantReadWriteLock(); + private Lock r = readWriteLock.readLock(); + private Lock w = readWriteLock.writeLock(); + + // 读操作上读锁 + public Object get(String key) { + r.lock(); + try { + // TODO 业务逻辑 + }finally { + r.unlock(); + } + return null; + } + + // 写操作上写锁 + public Object put(String key, Object value) { + w.lock(); + try { + // TODO 业务逻辑 + }finally { + w.unlock(); + } + return null; + } +} diff --git "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21303/sync\351\224\201/StockNumSale.java" "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/sync\351\224\201/StockNumSale.java" similarity index 98% rename from "src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21303/sync\351\224\201/StockNumSale.java" rename to "src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/sync\351\224\201/StockNumSale.java" index 36897b242100c67d7815564008addf137c720dc8..48388eefe935c7ec9e21d6bf15f493702118796b 100644 --- "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21303/sync\351\224\201/StockNumSale.java" +++ "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/sync\351\224\201/StockNumSale.java" @@ -1,4 +1,4 @@ -package 并发编程03.sync锁; +package 并发编程.demo.sync锁; /** * @Author idea diff --git "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/sync\351\224\201/SyncDemo.java" "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/sync\351\224\201/SyncDemo.java" new file mode 100644 index 0000000000000000000000000000000000000000..e71e122aaca16fc6364e73ad983ef43b4f8f1d4f --- /dev/null +++ "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/sync\351\224\201/SyncDemo.java" @@ -0,0 +1,65 @@ +package 并发编程.demo.sync锁; + + +import lombok.extern.slf4j.Slf4j; + +/** + * 结果可能是正数、负数、零。为什么呢?因为 Java 中对静态变量的自增,自减并不是原子操作。 + * 我们可以查看 i++和 i--(i 为静态变量)的 JVM 字节码指令 ( 可以在idea中安装一个jclasslib插件) + * + * 2种解决方式差不多,加的都是类锁,都是通过 synchronized 锁保证了临界区内代码的原子性 + * 1、public static synchronized void increment() { + * counter++; + * } + * + * public static synchronized void decrement() { + * counter--; + * 2、private static String lock = ""; + * + * public static void increment() { + * synchronized (lock){ + * counter++; + * } + * } + * + * public static void decrement() { + * synchronized (lock) { + * counter--; + * } + * 详细笔记链接 + * https://note.youdao.com/ynoteshare/index.html?id=57d2214df5e4fb961fc4135ee70d0a3f&type=notebook&_time=1679570583018#/CC779E5E55554F52B67C61A2BC79AE7D + */ +@Slf4j +public class SyncDemo { + + private static int counter = 0; + + public static void increment() { + counter++; + } + + public static void decrement() { + counter--; + } + + public static void main(String[] args) throws InterruptedException { + Thread t1 = new Thread(() -> { + for (int i = 0; i < 5000; i++) { + increment(); + } + }, "t1"); + Thread t2 = new Thread(() -> { + for (int i = 0; i < 5000; i++) { + decrement(); + } + }, "t2"); + t1.start(); + t2.start(); + t1.join(); + t2.join(); + + //思考: counter=? + log.info("最终结果:count = {}", counter); + } + +} \ No newline at end of file diff --git "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/wait\345\222\214notify\346\241\210\344\276\213/eg1/BaoZi.java" "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/wait\345\222\214notify\346\241\210\344\276\213/eg1/BaoZi.java" new file mode 100644 index 0000000000000000000000000000000000000000..3dc36a152101619f3701129b72abebdd64618c9e --- /dev/null +++ "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/wait\345\222\214notify\346\241\210\344\276\213/eg1/BaoZi.java" @@ -0,0 +1,33 @@ +package 并发编程.demo.wait和notify案例.eg1; + +public class BaoZi { + private String skin;//包子皮 + private String stuffing;//包子馅 + boolean flag = false;//包子资源是否存在 这里默认给定是没有 + + + public String getSkin() { + return skin; + } + + public void setSkin(String skin) { + this.skin = skin; + } + + public String getStuffing() { + return stuffing; + } + + public void setStuffing(String stuffing) { + this.stuffing = stuffing; + } + + public boolean isFlag() { + return flag; + } + + public void setFlag(boolean flag) { + this.flag = flag; + } + +} \ No newline at end of file diff --git "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/wait\345\222\214notify\346\241\210\344\276\213/eg1/Consumer.java" "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/wait\345\222\214notify\346\241\210\344\276\213/eg1/Consumer.java" new file mode 100644 index 0000000000000000000000000000000000000000..5a747479ce75bd7859cb134c18d446cd3c62e32a --- /dev/null +++ "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/wait\345\222\214notify\346\241\210\344\276\213/eg1/Consumer.java" @@ -0,0 +1,32 @@ +package 并发编程.demo.wait和notify案例.eg1; + +public class Consumer extends Thread { + private BaoZi bz; + + public Consumer(String name, BaoZi bz) { + //super调用父类Thread的构造方法 赋值name + super(name); + this.bz = bz; + } + + @Override + public void run() { + while (true) { + synchronized (bz) { + //判断包子资源是否存在 + if (bz.flag == false) { + try { + bz.wait();//包子如果没有,则进入等待 + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + System.out.println("消费者开始吃包子"); + //包子吃完后把资源设为false + bz.setFlag(false); + //唤醒生产者进行成产包子 + bz.notify(); + } + } + } +} \ No newline at end of file diff --git "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/wait\345\222\214notify\346\241\210\344\276\213/eg1/Producer.java" "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/wait\345\222\214notify\346\241\210\344\276\213/eg1/Producer.java" new file mode 100644 index 0000000000000000000000000000000000000000..d68be13f04ed86fa90ac56ecc3199d3fee323320 --- /dev/null +++ "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/wait\345\222\214notify\346\241\210\344\276\213/eg1/Producer.java" @@ -0,0 +1,48 @@ +package 并发编程.demo.wait和notify案例.eg1; + +public class Producer extends Thread { + private BaoZi bz; + private int count = 0; + + public Producer(String name, BaoZi bz) { + //super调用父类Thread的构造方法 赋值name + super(name); + this.bz = bz; + } + + @Override + public void run() { + while (true) { + synchronized (bz) { + //判断包子资源是否存在 + if (bz.flag == true) { + try { + bz.wait();//如果包子存在,则生产者进入等待 + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + //通过奇偶数来制作不同的包子,利于区分 + if (count % 2 == 0) { + bz.setSkin("白面皮"); + bz.setStuffing("猪肉大葱馅"); + System.out.println("生产者开始生产包子"); + System.out.println("生产了" + bz.getSkin() + bz.getStuffing() + "包子"); + count++; + } else if (count % 2 == 1) { + bz.setSkin("荞麦面"); + bz.setStuffing("胡萝卜粉条馅"); + System.out.println("生产者开始生产包子"); + System.out.println("生产了" + bz.getSkin() + bz.getStuffing() + "包子"); + count++; + } + //把包子资源设为true + bz.setFlag(true); + //唤醒消费者去吃包子 + System.out.println("生产者可以来吃包子啦"); + bz.notify(); + + } + } + } +} \ No newline at end of file diff --git "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/wait\345\222\214notify\346\241\210\344\276\213/eg1/Test.java" "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/wait\345\222\214notify\346\241\210\344\276\213/eg1/Test.java" new file mode 100644 index 0000000000000000000000000000000000000000..cbec90417441cc6be5a6231e8c74e578caabe1de --- /dev/null +++ "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/wait\345\222\214notify\346\241\210\344\276\213/eg1/Test.java" @@ -0,0 +1,36 @@ +package 并发编程.demo.wait和notify案例.eg1; + +/** + * @description + * 案例说明 + * 这里定义一个生产者生产包子,消费者吃包子的案例,生产者线程生产包子,消费者线程消费包子。当包子没有时(包子状态为false),生产者线程等待, + * 生产者线程生产包子(即包子状态为true),并通知消费者线程(解除消费者的等待状态),因为已经有包子了,那么生产者线程进入等待状态。接下来, + * 消费者线程能否进一步执行则取决于锁的获取情况。如果消费者获取到锁,那么就执行吃包子动作,包子吃完(包子状态为false), + * 并通知生产者线程(解除生产者的等待状态),消费者线程进入等待。生产者线程能否进一步执行则取决于锁的获取情况。 + * @author xiazihuai + * @create at 2023/4/4 21:07 + */ +public class Test { + + /** + * + 等待唤醒机制其实就是经典的“生产者与消费者”的问题。 + + wait和notify方法的使用注意事项: + 1、wait方法与notify方法必须要由同一个锁对象调用因为:对应的锁对象可以通过notify唤醒使用同一个锁对象调用的wait方法后的线程。 + 2、wait方法与notify方法是属于Object类的方法的因为:锁对象可以是任意对象,而任意对象的所属类都是继承了Object类的。 + 3、wait方法与notify方法必须要在同步代码块或者是同步函数中使用因为:必须要通过锁对象调用这2个方法。 + + 因为默认给定包子的flag为false,所以在创建生产者对象时,检测到flag为false,所以生产者开始生产包子,而消费者进行等待, + 当生产者生产出包子后,进行等待,消费者被唤醒,开始吃包子。 + */ + public static void main(String[] args) { + //定义一个包子对象,这个也是生产者和消费者共同的锁 + BaoZi bz = new BaoZi(); + //创建消费者和生产者对象,传递参数 + Consumer c = new Consumer("消费者", bz); + Producer p = new Producer("生产者", bz); + c.start(); + p.start(); + } +} \ No newline at end of file diff --git "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/wait\345\222\214notify\346\241\210\344\276\213/eg2/MyList.java" "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/wait\345\222\214notify\346\241\210\344\276\213/eg2/MyList.java" new file mode 100644 index 0000000000000000000000000000000000000000..351f199863e82caa5ea66f097330d859afee2edc --- /dev/null +++ "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/wait\345\222\214notify\346\241\210\344\276\213/eg2/MyList.java" @@ -0,0 +1,47 @@ +package 并发编程.demo.wait和notify案例.eg2; + +import java.util.ArrayList; +import java.util.List; + +/** + * @author xiazihuai + * @title MyList + * @create at 2023/4/4 21:13 + * 不使用等待/通知机制实现线程间通信,使用sleep()结合while(true)死循环法来实现多个线程间通信 + */ +public class MyList { + + private List list = new ArrayList<>(); + + public void add() { + list.add("王洪玉"); + } + + public int size() { + return list.size(); + } + + public static void main(String[] args) { + final MyList myList = new MyList(); + + Thread t1 = new Thread(() -> { + for (int i = 0; i < 10; i++) { + myList.add(); + System.out.println("当前线程," + Thread.currentThread().getName() + "添加了一个元素"); + } + }, "t1"); + + Thread t2 = new Thread(() -> { + while (true) { + + if (myList.size() == 5) { + System.out.println("当前线程收到通知:" + Thread.currentThread().getName() + "list size = 5线程停止。。。"); + throw new RuntimeException(); + } + } + }, "t2"); + + t1.start(); + t2.start(); + } +} diff --git "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/wait\345\222\214notify\346\241\210\344\276\213/eg2/MyList2.java" "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/wait\345\222\214notify\346\241\210\344\276\213/eg2/MyList2.java" new file mode 100644 index 0000000000000000000000000000000000000000..2d6055715d39d26efae2061b43fde82e53053ddf --- /dev/null +++ "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/wait\345\222\214notify\346\241\210\344\276\213/eg2/MyList2.java" @@ -0,0 +1,70 @@ +package 并发编程.demo.wait和notify案例.eg2; + +import java.util.ArrayList; +import java.util.List; + +/** + * @author xiazihuai + * @title MyList2 + * @create at 2023/4/4 21:14 + * + * 使用等待/通知机制实现线程间通信 + */ +public class MyList2 { + + private List list = new ArrayList<>(); + + public void add() { + list.add("王洪玉"); + } + + public int size() { + return list.size(); + } + + public static void main(String[] args) { + + final MyList2 myList = new MyList2(); + + //实例化出来一个lock + //当使用wait/notify时, + final Object lock = new Object(); + + Thread t1 = new Thread(() -> { + synchronized (lock) { + for (int i = 0; i < 10; i++) { + myList.add(); + System.out.println("当前线程," + Thread.currentThread().getName() + "添加了一个元素"); + try { + Thread.sleep(500); + } catch (InterruptedException e) { + e.printStackTrace(); + } + if (myList.size() == 5) { + System.out.println("已经发出通知。。。。"); + lock.notify(); //不释放锁,执行完for循环才释放锁 + } + } + } + }, "t1"); + + Thread t2 = new Thread(() -> { + synchronized (lock) { + if (myList.size() != 5) { + try { + System.out.println("进入t2。。。"); + lock.wait(); //释放对象锁 + } catch (InterruptedException e) { + e.printStackTrace(); + } + System.out.println("当前线程收到通知:" + Thread.currentThread().getName() + "list size = 5线程停止。。。"); + throw new RuntimeException(); + } + } + }, "t2"); + + t2.start(); + t1.start(); + } + +} diff --git "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21303/wait\350\260\203\347\224\250/WaitDemo.java" "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/wait\350\260\203\347\224\250/WaitDemo.java" similarity index 97% rename from "src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21303/wait\350\260\203\347\224\250/WaitDemo.java" rename to "src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/wait\350\260\203\347\224\250/WaitDemo.java" index 856fd912d6ebd17cb05dfe55de6f33334f3c953e..a38204eb8193397d161f5d5a02991abdd186037a 100644 --- "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21303/wait\350\260\203\347\224\250/WaitDemo.java" +++ "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/wait\350\260\203\347\224\250/WaitDemo.java" @@ -1,4 +1,4 @@ -package 并发编程03.wait调用; +package 并发编程.demo.wait调用; /** * @Author idea diff --git "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21306/\344\270\255\351\227\264\344\273\266\344\270\255\347\232\204\347\272\277\347\250\213\346\261\240\344\275\277\347\224\250/SpringAsyncDemo.java" "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/\344\270\255\351\227\264\344\273\266\344\270\255\347\232\204\347\272\277\347\250\213\346\261\240\344\275\277\347\224\250/SpringAsyncDemo.java" similarity index 88% rename from "src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21306/\344\270\255\351\227\264\344\273\266\344\270\255\347\232\204\347\272\277\347\250\213\346\261\240\344\275\277\347\224\250/SpringAsyncDemo.java" rename to "src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/\344\270\255\351\227\264\344\273\266\344\270\255\347\232\204\347\272\277\347\250\213\346\261\240\344\275\277\347\224\250/SpringAsyncDemo.java" index fc9b2e379d84518c78d57742569dc33881cfbf12..7d26ca33675d26b466d9a66daff9c947b5286575 100644 --- "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21306/\344\270\255\351\227\264\344\273\266\344\270\255\347\232\204\347\272\277\347\250\213\346\261\240\344\275\277\347\224\250/SpringAsyncDemo.java" +++ "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/\344\270\255\351\227\264\344\273\266\344\270\255\347\232\204\347\272\277\347\250\213\346\261\240\344\275\277\347\224\250/SpringAsyncDemo.java" @@ -1,4 +1,4 @@ -package 并发编程06.中间件中的线程池使用; +package 并发编程.demo.中间件中的线程池使用; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; diff --git "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21306/\344\270\255\351\227\264\344\273\266\344\270\255\347\232\204\347\272\277\347\250\213\346\261\240\344\275\277\347\224\250/config/AsyncExecuteConfig.java" "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/\344\270\255\351\227\264\344\273\266\344\270\255\347\232\204\347\272\277\347\250\213\346\261\240\344\275\277\347\224\250/config/AsyncExecuteConfig.java" similarity index 87% rename from "src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21306/\344\270\255\351\227\264\344\273\266\344\270\255\347\232\204\347\272\277\347\250\213\346\261\240\344\275\277\347\224\250/config/AsyncExecuteConfig.java" rename to "src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/\344\270\255\351\227\264\344\273\266\344\270\255\347\232\204\347\272\277\347\250\213\346\261\240\344\275\277\347\224\250/config/AsyncExecuteConfig.java" index 9542bc8b3e174f21de05ce6c4949d850ac9230ba..e01782e797d06c44373a2f27ce9d4401ae00dfcc 100644 --- "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21306/\344\270\255\351\227\264\344\273\266\344\270\255\347\232\204\347\272\277\347\250\213\346\261\240\344\275\277\347\224\250/config/AsyncExecuteConfig.java" +++ "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/\344\270\255\351\227\264\344\273\266\344\270\255\347\232\204\347\272\277\347\250\213\346\261\240\344\275\277\347\224\250/config/AsyncExecuteConfig.java" @@ -1,7 +1,6 @@ -package 并发编程06.中间件中的线程池使用.config; +package 并发编程.demo.中间件中的线程池使用.config; import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; import org.springframework.scheduling.annotation.AsyncConfigurerSupport; import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; diff --git "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21306/\344\270\255\351\227\264\344\273\266\344\270\255\347\232\204\347\272\277\347\250\213\346\261\240\344\275\277\347\224\250/controller/TestController.java" "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/\344\270\255\351\227\264\344\273\266\344\270\255\347\232\204\347\272\277\347\250\213\346\261\240\344\275\277\347\224\250/controller/TestController.java" similarity index 87% rename from "src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21306/\344\270\255\351\227\264\344\273\266\344\270\255\347\232\204\347\272\277\347\250\213\346\261\240\344\275\277\347\224\250/controller/TestController.java" rename to "src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/\344\270\255\351\227\264\344\273\266\344\270\255\347\232\204\347\272\277\347\250\213\346\261\240\344\275\277\347\224\250/controller/TestController.java" index 904d2ea2e70293e162bc60be243b201848b0cfcc..4341688d30917606b7436a04dc9a34aaa1fe3883 100644 --- "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21306/\344\270\255\351\227\264\344\273\266\344\270\255\347\232\204\347\272\277\347\250\213\346\261\240\344\275\277\347\224\250/controller/TestController.java" +++ "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/\344\270\255\351\227\264\344\273\266\344\270\255\347\232\204\347\272\277\347\250\213\346\261\240\344\275\277\347\224\250/controller/TestController.java" @@ -1,10 +1,10 @@ -package 并发编程06.中间件中的线程池使用.controller; +package 并发编程.demo.中间件中的线程池使用.controller; import org.springframework.context.ApplicationContext; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; -import 并发编程06.中间件中的线程池使用.service.AsyncService; +import 并发编程.demo.中间件中的线程池使用.service.AsyncService; import javax.annotation.Resource; import java.util.concurrent.ExecutorService; diff --git "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21306/\344\270\255\351\227\264\344\273\266\344\270\255\347\232\204\347\272\277\347\250\213\346\261\240\344\275\277\347\224\250/service/AsyncService.java" "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/\344\270\255\351\227\264\344\273\266\344\270\255\347\232\204\347\272\277\347\250\213\346\261\240\344\275\277\347\224\250/service/AsyncService.java" similarity index 87% rename from "src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21306/\344\270\255\351\227\264\344\273\266\344\270\255\347\232\204\347\272\277\347\250\213\346\261\240\344\275\277\347\224\250/service/AsyncService.java" rename to "src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/\344\270\255\351\227\264\344\273\266\344\270\255\347\232\204\347\272\277\347\250\213\346\261\240\344\275\277\347\224\250/service/AsyncService.java" index fa63f2eaa081f729eff0a31a1917be72dfc3573d..b672beeac9aaa868c47c755b7ae7f9a2c69bfe4d 100644 --- "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21306/\344\270\255\351\227\264\344\273\266\344\270\255\347\232\204\347\272\277\347\250\213\346\261\240\344\275\277\347\224\250/service/AsyncService.java" +++ "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/\344\270\255\351\227\264\344\273\266\344\270\255\347\232\204\347\272\277\347\250\213\346\261\240\344\275\277\347\224\250/service/AsyncService.java" @@ -1,4 +1,4 @@ -package 并发编程06.中间件中的线程池使用.service; +package 并发编程.demo.中间件中的线程池使用.service; import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Service; diff --git "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21307/\345\216\237\345\255\220\347\261\273/AtomicDemo.java" "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/\345\216\237\345\255\220\347\261\273/AtomicDemo.java" similarity index 98% rename from "src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21307/\345\216\237\345\255\220\347\261\273/AtomicDemo.java" rename to "src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/\345\216\237\345\255\220\347\261\273/AtomicDemo.java" index 2d1ab40bfdc24b2f5a0139c40363466996e0eebc..57375685d6c86817c63f8f776dd11598e505cb30 100644 --- "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21307/\345\216\237\345\255\220\347\261\273/AtomicDemo.java" +++ "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/\345\216\237\345\255\220\347\261\273/AtomicDemo.java" @@ -1,4 +1,4 @@ -package 并发编程07.原子类; +package 并发编程.demo.原子类; import org.junit.jupiter.api.Test; diff --git "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21301/\345\256\210\346\212\244\347\272\277\347\250\213/DaemonThreadDemo.java" "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/\345\256\210\346\212\244\347\272\277\347\250\213/DaemonThreadDemo.java" similarity index 94% rename from "src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21301/\345\256\210\346\212\244\347\272\277\347\250\213/DaemonThreadDemo.java" rename to "src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/\345\256\210\346\212\244\347\272\277\347\250\213/DaemonThreadDemo.java" index 8f87f2bf287c7360be2719ce557302f16b00ec6f..82ddd8afbb6dfbe942190517b951a8f4340a4692 100644 --- "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21301/\345\256\210\346\212\244\347\272\277\347\250\213/DaemonThreadDemo.java" +++ "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/\345\256\210\346\212\244\347\272\277\347\250\213/DaemonThreadDemo.java" @@ -1,4 +1,4 @@ -package 并发编程01.守护线程; +package 并发编程.demo.守护线程; /** * @Author idea diff --git "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21301/\345\256\210\346\212\244\347\272\277\347\250\213/SystemExitDemo.java" "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/\345\256\210\346\212\244\347\272\277\347\250\213/SystemExitDemo.java" similarity index 92% rename from "src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21301/\345\256\210\346\212\244\347\272\277\347\250\213/SystemExitDemo.java" rename to "src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/\345\256\210\346\212\244\347\272\277\347\250\213/SystemExitDemo.java" index 4f7e5a0e223c5307ff61d26276be60f2ab220237..5879765940c31beff8657fbc534d43100ca07593 100644 --- "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21301/\345\256\210\346\212\244\347\272\277\347\250\213/SystemExitDemo.java" +++ "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/\345\256\210\346\212\244\347\272\277\347\250\213/SystemExitDemo.java" @@ -1,6 +1,4 @@ -package 并发编程01.守护线程; - -import java.util.concurrent.CountDownLatch; +package 并发编程.demo.守护线程; /** * @Author idea diff --git "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21304/\346\211\213\345\206\231\345\216\237\347\224\237Lock/AbstractQueuedSynchronizer.java" "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/\346\211\213\345\206\231\345\216\237\347\224\237Lock/AbstractQueuedSynchronizer.java" similarity index 98% rename from "src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21304/\346\211\213\345\206\231\345\216\237\347\224\237Lock/AbstractQueuedSynchronizer.java" rename to "src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/\346\211\213\345\206\231\345\216\237\347\224\237Lock/AbstractQueuedSynchronizer.java" index 5bfc8956b2e0079aa9cb16214034e0b024b12169..77ebad909a0e3bebd9008f0c8fc86d53c6d3585d 100644 --- "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21304/\346\211\213\345\206\231\345\216\237\347\224\237Lock/AbstractQueuedSynchronizer.java" +++ "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/\346\211\213\345\206\231\345\216\237\347\224\237Lock/AbstractQueuedSynchronizer.java" @@ -1,4 +1,4 @@ -package 并发编程04.手写原生Lock; +package 并发编程.demo.手写原生Lock; /** diff --git "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21304/\346\211\213\345\206\231\345\216\237\347\224\237Lock/ILock.java" "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/\346\211\213\345\206\231\345\216\237\347\224\237Lock/ILock.java" similarity index 74% rename from "src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21304/\346\211\213\345\206\231\345\216\237\347\224\237Lock/ILock.java" rename to "src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/\346\211\213\345\206\231\345\216\237\347\224\237Lock/ILock.java" index dbc7c02c9e18b179a5aa720c32a73a7804a9c46b..5df980c92a00633509b3fc06f2057370d49f026d 100644 --- "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21304/\346\211\213\345\206\231\345\216\237\347\224\237Lock/ILock.java" +++ "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/\346\211\213\345\206\231\345\216\237\347\224\237Lock/ILock.java" @@ -1,4 +1,4 @@ -package 并发编程04.手写原生Lock; +package 并发编程.demo.手写原生Lock; /** * @Author idea diff --git "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21304/\346\211\213\345\206\231\345\216\237\347\224\237Lock/MySimpleLock.java" "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/\346\211\213\345\206\231\345\216\237\347\224\237Lock/MySimpleLock.java" similarity index 97% rename from "src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21304/\346\211\213\345\206\231\345\216\237\347\224\237Lock/MySimpleLock.java" rename to "src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/\346\211\213\345\206\231\345\216\237\347\224\237Lock/MySimpleLock.java" index f60f62a5dbaca77b36be4191a1d668cb4e3c8a86..fee54532b3403437461fa59fae5d14618d0f5ffb 100644 --- "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21304/\346\211\213\345\206\231\345\216\237\347\224\237Lock/MySimpleLock.java" +++ "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/\346\211\213\345\206\231\345\216\237\347\224\237Lock/MySimpleLock.java" @@ -1,4 +1,4 @@ -package 并发编程04.手写原生Lock; +package 并发编程.demo.手写原生Lock; import sun.misc.Unsafe; diff --git "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21307/\346\216\245\345\217\243\350\257\267\346\261\202\346\254\241\346\225\260\347\273\237\350\256\241/SpringCountApplication.java" "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/\346\216\245\345\217\243\350\257\267\346\261\202\346\254\241\346\225\260\347\273\237\350\256\241/SpringCountApplication.java" similarity index 87% rename from "src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21307/\346\216\245\345\217\243\350\257\267\346\261\202\346\254\241\346\225\260\347\273\237\350\256\241/SpringCountApplication.java" rename to "src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/\346\216\245\345\217\243\350\257\267\346\261\202\346\254\241\346\225\260\347\273\237\350\256\241/SpringCountApplication.java" index 9dc66f54c07c402dcae08943579dbf359105e2b7..2e95c136a8d505bcd3f25e848df07f7060fb8e76 100644 --- "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21307/\346\216\245\345\217\243\350\257\267\346\261\202\346\254\241\346\225\260\347\273\237\350\256\241/SpringCountApplication.java" +++ "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/\346\216\245\345\217\243\350\257\267\346\261\202\346\254\241\346\225\260\347\273\237\350\256\241/SpringCountApplication.java" @@ -1,4 +1,4 @@ -package 并发编程07.接口请求次数统计; +package 并发编程.demo.接口请求次数统计; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; diff --git "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21307/\346\216\245\345\217\243\350\257\267\346\261\202\346\254\241\346\225\260\347\273\237\350\256\241/controller/TestController.java" "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/\346\216\245\345\217\243\350\257\267\346\261\202\346\254\241\346\225\260\347\273\237\350\256\241/controller/TestController.java" similarity index 92% rename from "src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21307/\346\216\245\345\217\243\350\257\267\346\261\202\346\254\241\346\225\260\347\273\237\350\256\241/controller/TestController.java" rename to "src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/\346\216\245\345\217\243\350\257\267\346\261\202\346\254\241\346\225\260\347\273\237\350\256\241/controller/TestController.java" index 0ce646d77bc0d30c18033053f569224e0865c74e..341a582c8e88d6a22ab0c5e34b4bca71279f9fe9 100644 --- "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21307/\346\216\245\345\217\243\350\257\267\346\261\202\346\254\241\346\225\260\347\273\237\350\256\241/controller/TestController.java" +++ "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/\346\216\245\345\217\243\350\257\267\346\261\202\346\254\241\346\225\260\347\273\237\350\256\241/controller/TestController.java" @@ -1,4 +1,4 @@ -package 并发编程07.接口请求次数统计.controller; +package 并发编程.demo.接口请求次数统计.controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; diff --git "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21303/\346\237\245\347\234\213\345\206\205\345\255\230\345\270\203\345\261\200\344\277\241\346\201\257/MarkWordDemo_1.java" "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/\346\237\245\347\234\213\345\206\205\345\255\230\345\270\203\345\261\200\344\277\241\346\201\257/MarkWordDemo_1.java" similarity index 86% rename from "src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21303/\346\237\245\347\234\213\345\206\205\345\255\230\345\270\203\345\261\200\344\277\241\346\201\257/MarkWordDemo_1.java" rename to "src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/\346\237\245\347\234\213\345\206\205\345\255\230\345\270\203\345\261\200\344\277\241\346\201\257/MarkWordDemo_1.java" index e5ffd43cf5ac955fbf5d4ac9abfaa3c4f51e679b..516bc69a60ce1f846b1f7153443f6d7e4c9493cf 100644 --- "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21303/\346\237\245\347\234\213\345\206\205\345\255\230\345\270\203\345\261\200\344\277\241\346\201\257/MarkWordDemo_1.java" +++ "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/\346\237\245\347\234\213\345\206\205\345\255\230\345\270\203\345\261\200\344\277\241\346\201\257/MarkWordDemo_1.java" @@ -1,4 +1,4 @@ -package 并发编程03.查看内存布局信息; +package 并发编程.demo.查看内存布局信息; import org.openjdk.jol.info.ClassLayout; diff --git "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21303/\346\237\245\347\234\213\345\206\205\345\255\230\345\270\203\345\261\200\344\277\241\346\201\257/MarkWordDemo_2.java" "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/\346\237\245\347\234\213\345\206\205\345\255\230\345\270\203\345\261\200\344\277\241\346\201\257/MarkWordDemo_2.java" similarity index 91% rename from "src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21303/\346\237\245\347\234\213\345\206\205\345\255\230\345\270\203\345\261\200\344\277\241\346\201\257/MarkWordDemo_2.java" rename to "src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/\346\237\245\347\234\213\345\206\205\345\255\230\345\270\203\345\261\200\344\277\241\346\201\257/MarkWordDemo_2.java" index a8e655afdced5e20f567b0eaeecf6b7019747a7c..d1461969422ca1f1807dd286312a3677c666e733 100644 --- "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21303/\346\237\245\347\234\213\345\206\205\345\255\230\345\270\203\345\261\200\344\277\241\346\201\257/MarkWordDemo_2.java" +++ "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/\346\237\245\347\234\213\345\206\205\345\255\230\345\270\203\345\261\200\344\277\241\346\201\257/MarkWordDemo_2.java" @@ -1,4 +1,4 @@ -package 并发编程03.查看内存布局信息; +package 并发编程.demo.查看内存布局信息; import org.openjdk.jol.info.ClassLayout; diff --git "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21303/\346\237\245\347\234\213\345\206\205\345\255\230\345\270\203\345\261\200\344\277\241\346\201\257/MarkWordDemo_3.java" "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/\346\237\245\347\234\213\345\206\205\345\255\230\345\270\203\345\261\200\344\277\241\346\201\257/MarkWordDemo_3.java" similarity index 95% rename from "src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21303/\346\237\245\347\234\213\345\206\205\345\255\230\345\270\203\345\261\200\344\277\241\346\201\257/MarkWordDemo_3.java" rename to "src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/\346\237\245\347\234\213\345\206\205\345\255\230\345\270\203\345\261\200\344\277\241\346\201\257/MarkWordDemo_3.java" index f6ce39273e582f2af739dd719c48ccf802fc60a8..ce42f4d5146e5da05fe3876700fb21f94c64c1f0 100644 --- "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21303/\346\237\245\347\234\213\345\206\205\345\255\230\345\270\203\345\261\200\344\277\241\346\201\257/MarkWordDemo_3.java" +++ "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/\346\237\245\347\234\213\345\206\205\345\255\230\345\270\203\345\261\200\344\277\241\346\201\257/MarkWordDemo_3.java" @@ -1,4 +1,4 @@ -package 并发编程03.查看内存布局信息; +package 并发编程.demo.查看内存布局信息; import org.openjdk.jol.info.ClassLayout; diff --git "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21303/\346\237\245\347\234\213\345\206\205\345\255\230\345\270\203\345\261\200\344\277\241\346\201\257/MarkWordDemo_4.java" "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/\346\237\245\347\234\213\345\206\205\345\255\230\345\270\203\345\261\200\344\277\241\346\201\257/MarkWordDemo_4.java" similarity index 97% rename from "src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21303/\346\237\245\347\234\213\345\206\205\345\255\230\345\270\203\345\261\200\344\277\241\346\201\257/MarkWordDemo_4.java" rename to "src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/\346\237\245\347\234\213\345\206\205\345\255\230\345\270\203\345\261\200\344\277\241\346\201\257/MarkWordDemo_4.java" index 0ecfa088222cdf490ac848c697987b6b054fa744..0235934d757bbc12a89f6231db2d3f30a7836dae 100644 --- "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21303/\346\237\245\347\234\213\345\206\205\345\255\230\345\270\203\345\261\200\344\277\241\346\201\257/MarkWordDemo_4.java" +++ "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/\346\237\245\347\234\213\345\206\205\345\255\230\345\270\203\345\261\200\344\277\241\346\201\257/MarkWordDemo_4.java" @@ -1,4 +1,4 @@ -package 并发编程03.查看内存布局信息; +package 并发编程.demo.查看内存布局信息; import org.openjdk.jol.info.ClassLayout; import org.slf4j.Logger; diff --git "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21300/\346\250\241\346\213\237\345\271\266\345\217\221\350\257\267\346\261\202\345\234\272\346\231\257/ThreadDemo.java" "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/\346\250\241\346\213\237\345\271\266\345\217\221\350\257\267\346\261\202\345\234\272\346\231\257/ThreadDemo.java" similarity index 95% rename from "src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21300/\346\250\241\346\213\237\345\271\266\345\217\221\350\257\267\346\261\202\345\234\272\346\231\257/ThreadDemo.java" rename to "src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/\346\250\241\346\213\237\345\271\266\345\217\221\350\257\267\346\261\202\345\234\272\346\231\257/ThreadDemo.java" index c57c376f504e5f3c6ce2e85f95bdda3913189e4a..6d58a8ed2c48b0151c7d8d8974cea98c0df54d09 100644 --- "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21300/\346\250\241\346\213\237\345\271\266\345\217\221\350\257\267\346\261\202\345\234\272\346\231\257/ThreadDemo.java" +++ "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/\346\250\241\346\213\237\345\271\266\345\217\221\350\257\267\346\261\202\345\234\272\346\231\257/ThreadDemo.java" @@ -1,4 +1,4 @@ -package 并发编程00.模拟并发请求场景; +package 并发编程.demo.模拟并发请求场景; import java.util.concurrent.CountDownLatch; diff --git "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21301/\347\272\277\347\250\213\344\274\230\345\205\210\347\272\247/ThreadPriorityDemo.java" "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/\347\272\277\347\250\213\344\274\230\345\205\210\347\272\247/ThreadPriorityDemo.java" similarity index 97% rename from "src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21301/\347\272\277\347\250\213\344\274\230\345\205\210\347\272\247/ThreadPriorityDemo.java" rename to "src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/\347\272\277\347\250\213\344\274\230\345\205\210\347\272\247/ThreadPriorityDemo.java" index 27f3c16714ce95de80146c8c4be1692bca28d59f..f392b4be475b5c77bcd18e78043a0529ea1921d6 100644 --- "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21301/\347\272\277\347\250\213\344\274\230\345\205\210\347\272\247/ThreadPriorityDemo.java" +++ "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/\347\272\277\347\250\213\344\274\230\345\205\210\347\272\247/ThreadPriorityDemo.java" @@ -1,4 +1,4 @@ -package 并发编程01.线程优先级; +package 并发编程.demo.线程优先级; /** * 优先级和操作系统及虚拟机版本相关。 diff --git "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21301/\347\272\277\347\250\213\345\210\206\347\273\204/ThreadGroupDemo.java" "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/\347\272\277\347\250\213\345\210\206\347\273\204/ThreadGroupDemo.java" similarity index 98% rename from "src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21301/\347\272\277\347\250\213\345\210\206\347\273\204/ThreadGroupDemo.java" rename to "src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/\347\272\277\347\250\213\345\210\206\347\273\204/ThreadGroupDemo.java" index 7fa3eb04090ffbf35d915f34d2eaae8c255ea8b5..a7c33facb412ea729adcb98cc64f754d49ce4332 100644 --- "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21301/\347\272\277\347\250\213\345\210\206\347\273\204/ThreadGroupDemo.java" +++ "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/\347\272\277\347\250\213\345\210\206\347\273\204/ThreadGroupDemo.java" @@ -1,4 +1,4 @@ -package 并发编程01.线程分组; +package 并发编程.demo.线程分组; import java.util.ArrayList; import java.util.List; diff --git "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21301/\347\272\277\347\250\213\345\267\245\345\216\202/SimpleThreadFactory.java" "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/\347\272\277\347\250\213\345\267\245\345\216\202/SimpleThreadFactory.java" similarity index 97% rename from "src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21301/\347\272\277\347\250\213\345\267\245\345\216\202/SimpleThreadFactory.java" rename to "src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/\347\272\277\347\250\213\345\267\245\345\216\202/SimpleThreadFactory.java" index 41bb4393edbde5226eea778a69a77d0841e33fba..80206b15489bf631201bb5f24b1c75d90cc8fd30 100644 --- "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21301/\347\272\277\347\250\213\345\267\245\345\216\202/SimpleThreadFactory.java" +++ "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/\347\272\277\347\250\213\345\267\245\345\216\202/SimpleThreadFactory.java" @@ -1,4 +1,4 @@ -package 并发编程01.线程工厂; +package 并发编程.demo.线程工厂; import java.util.concurrent.CountDownLatch; import java.util.concurrent.ThreadFactory; diff --git "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21301/\347\272\277\347\250\213\345\274\202\345\270\270\346\215\225\350\216\267\345\231\250/ThreadExceptionCatchDemo.java" "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/\347\272\277\347\250\213\345\274\202\345\270\270\346\215\225\350\216\267\345\231\250/ThreadExceptionCatchDemo.java" similarity index 94% rename from "src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21301/\347\272\277\347\250\213\345\274\202\345\270\270\346\215\225\350\216\267\345\231\250/ThreadExceptionCatchDemo.java" rename to "src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/\347\272\277\347\250\213\345\274\202\345\270\270\346\215\225\350\216\267\345\231\250/ThreadExceptionCatchDemo.java" index 553cc9d50b1048b2cb13b520c4f2153401fd429b..a3009cc37721369cba9635bd41ca150f8405e63d 100644 --- "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21301/\347\272\277\347\250\213\345\274\202\345\270\270\346\215\225\350\216\267\345\231\250/ThreadExceptionCatchDemo.java" +++ "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/\347\272\277\347\250\213\345\274\202\345\270\270\346\215\225\350\216\267\345\231\250/ThreadExceptionCatchDemo.java" @@ -1,4 +1,4 @@ -package 并发编程01.线程异常捕获器; +package 并发编程.demo.线程异常捕获器; /** * @Author idea diff --git "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21308/\347\272\277\347\250\213\346\234\254\345\234\260\345\217\230\351\207\217/Application.java" "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/\347\272\277\347\250\213\346\234\254\345\234\260\345\217\230\351\207\217/Application.java" similarity index 88% rename from "src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21308/\347\272\277\347\250\213\346\234\254\345\234\260\345\217\230\351\207\217/Application.java" rename to "src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/\347\272\277\347\250\213\346\234\254\345\234\260\345\217\230\351\207\217/Application.java" index c6993b4ddff44a5213980ad3514fc91d10dff630..92e639e4a2bd50e0dfdb20ce613965ec4e0c0f93 100644 --- "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21308/\347\272\277\347\250\213\346\234\254\345\234\260\345\217\230\351\207\217/Application.java" +++ "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/\347\272\277\347\250\213\346\234\254\345\234\260\345\217\230\351\207\217/Application.java" @@ -1,4 +1,4 @@ -package 并发编程08.线程本地变量; +package 并发编程.demo.线程本地变量; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; diff --git "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21308/\347\272\277\347\250\213\346\234\254\345\234\260\345\217\230\351\207\217/config/InterceptorConfig.java" "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/\347\272\277\347\250\213\346\234\254\345\234\260\345\217\230\351\207\217/config/InterceptorConfig.java" similarity index 90% rename from "src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21308/\347\272\277\347\250\213\346\234\254\345\234\260\345\217\230\351\207\217/config/InterceptorConfig.java" rename to "src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/\347\272\277\347\250\213\346\234\254\345\234\260\345\217\230\351\207\217/config/InterceptorConfig.java" index a900fef822ae1e3744f72cdf2cbdb8dde65c2a17..5e98ab0150e623f6ef61c2a6f949d4807a78afc7 100644 --- "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21308/\347\272\277\347\250\213\346\234\254\345\234\260\345\217\230\351\207\217/config/InterceptorConfig.java" +++ "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/\347\272\277\347\250\213\346\234\254\345\234\260\345\217\230\351\207\217/config/InterceptorConfig.java" @@ -1,4 +1,4 @@ -package 并发编程08.线程本地变量.config; +package 并发编程.demo.线程本地变量.config; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; diff --git "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21308/\347\272\277\347\250\213\346\234\254\345\234\260\345\217\230\351\207\217/config/TimeCountInterceptor.java" "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/\347\272\277\347\250\213\346\234\254\345\234\260\345\217\230\351\207\217/config/TimeCountInterceptor.java" similarity index 94% rename from "src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21308/\347\272\277\347\250\213\346\234\254\345\234\260\345\217\230\351\207\217/config/TimeCountInterceptor.java" rename to "src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/\347\272\277\347\250\213\346\234\254\345\234\260\345\217\230\351\207\217/config/TimeCountInterceptor.java" index e19a75f1102993fae9d70bfb7b67eefe1e676c19..cb3f043ed9f9eb0b69dc19259e25dfdbe5345bf1 100644 --- "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21308/\347\272\277\347\250\213\346\234\254\345\234\260\345\217\230\351\207\217/config/TimeCountInterceptor.java" +++ "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/\347\272\277\347\250\213\346\234\254\345\234\260\345\217\230\351\207\217/config/TimeCountInterceptor.java" @@ -1,4 +1,4 @@ -package 并发编程08.线程本地变量.config; +package 并发编程.demo.线程本地变量.config; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.HandlerInterceptor; @@ -6,7 +6,6 @@ import org.springframework.web.servlet.ModelAndView; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; -import java.util.HashMap; /** * @Author idea diff --git "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21308/\347\272\277\347\250\213\346\234\254\345\234\260\345\217\230\351\207\217/controller/TestController.java" "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/\347\272\277\347\250\213\346\234\254\345\234\260\345\217\230\351\207\217/controller/TestController.java" similarity index 90% rename from "src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21308/\347\272\277\347\250\213\346\234\254\345\234\260\345\217\230\351\207\217/controller/TestController.java" rename to "src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/\347\272\277\347\250\213\346\234\254\345\234\260\345\217\230\351\207\217/controller/TestController.java" index cfbae7df1aabae0bbc2ee4bddee66d665840ec1f..d3bf9f7d16921754f31225060317f1697ff5c25d 100644 --- "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21308/\347\272\277\347\250\213\346\234\254\345\234\260\345\217\230\351\207\217/controller/TestController.java" +++ "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/\347\272\277\347\250\213\346\234\254\345\234\260\345\217\230\351\207\217/controller/TestController.java" @@ -1,4 +1,4 @@ -package 并发编程08.线程本地变量.controller; +package 并发编程.demo.线程本地变量.controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; diff --git "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21306/\347\272\277\347\250\213\346\261\240\344\275\277\347\224\250\346\241\210\344\276\213/AuditExecutorDemo.java" "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/\347\272\277\347\250\213\346\261\240\344\275\277\347\224\250\346\241\210\344\276\213/AuditExecutorDemo.java" similarity index 96% rename from "src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21306/\347\272\277\347\250\213\346\261\240\344\275\277\347\224\250\346\241\210\344\276\213/AuditExecutorDemo.java" rename to "src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/\347\272\277\347\250\213\346\261\240\344\275\277\347\224\250\346\241\210\344\276\213/AuditExecutorDemo.java" index 107d734d802bea2cc652518b3fe0f92e2d51acb9..4b91d1cc15af5c6ba42302ae63edd5b8dd85a5f1 100644 --- "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21306/\347\272\277\347\250\213\346\261\240\344\275\277\347\224\250\346\241\210\344\276\213/AuditExecutorDemo.java" +++ "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/\347\272\277\347\250\213\346\261\240\344\275\277\347\224\250\346\241\210\344\276\213/AuditExecutorDemo.java" @@ -1,4 +1,4 @@ -package 并发编程06.线程池使用案例; +package 并发编程.demo.线程池使用案例; import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.ThreadPoolExecutor; diff --git "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21306/\347\272\277\347\250\213\346\261\240\344\275\277\347\224\250\346\241\210\344\276\213/ThreadExecutorDemo.java" "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/\347\272\277\347\250\213\346\261\240\344\275\277\347\224\250\346\241\210\344\276\213/ThreadExecutorDemo.java" similarity index 90% rename from "src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21306/\347\272\277\347\250\213\346\261\240\344\275\277\347\224\250\346\241\210\344\276\213/ThreadExecutorDemo.java" rename to "src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/\347\272\277\347\250\213\346\261\240\344\275\277\347\224\250\346\241\210\344\276\213/ThreadExecutorDemo.java" index 34249c916f1a3e7235a52f66d5e9e021f1698d96..29fb8414c0011cddab3f56d9eb04c30567d9ad6d 100644 --- "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21306/\347\272\277\347\250\213\346\261\240\344\275\277\347\224\250\346\241\210\344\276\213/ThreadExecutorDemo.java" +++ "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/\347\272\277\347\250\213\346\261\240\344\275\277\347\224\250\346\241\210\344\276\213/ThreadExecutorDemo.java" @@ -1,7 +1,6 @@ -package 并发编程06.线程池使用案例; +package 并发编程.demo.线程池使用案例; import java.util.concurrent.ArrayBlockingQueue; -import java.util.concurrent.ExecutorService; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; diff --git "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21306/\347\272\277\347\250\213\346\261\240\344\275\277\347\224\250\346\241\210\344\276\213/UserRegistryDemo.java" "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/\347\272\277\347\250\213\346\261\240\344\275\277\347\224\250\346\241\210\344\276\213/UserRegistryDemo.java" similarity index 96% rename from "src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21306/\347\272\277\347\250\213\346\261\240\344\275\277\347\224\250\346\241\210\344\276\213/UserRegistryDemo.java" rename to "src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/\347\272\277\347\250\213\346\261\240\344\275\277\347\224\250\346\241\210\344\276\213/UserRegistryDemo.java" index 4c6cd19bc43d1c3ecc68b778615f145cab515f0d..0f5e48936adab2321d67da15e1441f608b36a27d 100644 --- "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21306/\347\272\277\347\250\213\346\261\240\344\275\277\347\224\250\346\241\210\344\276\213/UserRegistryDemo.java" +++ "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/\347\272\277\347\250\213\346\261\240\344\275\277\347\224\250\346\241\210\344\276\213/UserRegistryDemo.java" @@ -1,4 +1,4 @@ -package 并发编程06.线程池使用案例; +package 并发编程.demo.线程池使用案例; import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.ThreadPoolExecutor; diff --git "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21302/\347\272\277\347\250\213\346\261\240\345\205\263\351\227\255/ExecutorShutDownDemo.java" "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/\347\272\277\347\250\213\346\261\240\345\205\263\351\227\255/ExecutorShutDownDemo.java" similarity index 97% rename from "src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21302/\347\272\277\347\250\213\346\261\240\345\205\263\351\227\255/ExecutorShutDownDemo.java" rename to "src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/\347\272\277\347\250\213\346\261\240\345\205\263\351\227\255/ExecutorShutDownDemo.java" index c782ef60c090d9b57725b198523f7020636b8f85..ba5be681a813f875f86a45d2e97e104447598973 100644 --- "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21302/\347\272\277\347\250\213\346\261\240\345\205\263\351\227\255/ExecutorShutDownDemo.java" +++ "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/\347\272\277\347\250\213\346\261\240\345\205\263\351\227\255/ExecutorShutDownDemo.java" @@ -1,4 +1,4 @@ -package 并发编程02.线程池关闭; +package 并发编程.demo.线程池关闭; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; diff --git "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21302/\347\272\277\347\250\213\346\261\240\345\205\263\351\227\255/ExecutorShutDownDemo2.java" "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/\347\272\277\347\250\213\346\261\240\345\205\263\351\227\255/ExecutorShutDownDemo2.java" similarity index 98% rename from "src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21302/\347\272\277\347\250\213\346\261\240\345\205\263\351\227\255/ExecutorShutDownDemo2.java" rename to "src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/\347\272\277\347\250\213\346\261\240\345\205\263\351\227\255/ExecutorShutDownDemo2.java" index b975f0940ca019359cc823cfa2188691449d3670..9f863963f31217d935663f458f243ba4cfd4b948 100644 --- "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21302/\347\272\277\347\250\213\346\261\240\345\205\263\351\227\255/ExecutorShutDownDemo2.java" +++ "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/\347\272\277\347\250\213\346\261\240\345\205\263\351\227\255/ExecutorShutDownDemo2.java" @@ -1,4 +1,4 @@ -package 并发编程02.线程池关闭; +package 并发编程.demo.线程池关闭; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; diff --git "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21301/\347\272\277\347\250\213\346\261\240\346\241\210\344\276\213/ThreadPoolDemo.java" "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/\347\272\277\347\250\213\346\261\240\346\241\210\344\276\213/ThreadPoolDemo.java" similarity index 94% rename from "src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21301/\347\272\277\347\250\213\346\261\240\346\241\210\344\276\213/ThreadPoolDemo.java" rename to "src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/\347\272\277\347\250\213\346\261\240\346\241\210\344\276\213/ThreadPoolDemo.java" index 7d9673886c4f4a22c3bb56138dfd6580349591e6..2e2013e299022e36392f4328991f5a539b8a27d5 100644 --- "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21301/\347\272\277\347\250\213\346\261\240\346\241\210\344\276\213/ThreadPoolDemo.java" +++ "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/\347\272\277\347\250\213\346\261\240\346\241\210\344\276\213/ThreadPoolDemo.java" @@ -1,4 +1,4 @@ -package 并发编程01.线程池案例; +package 并发编程.demo.线程池案例; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; diff --git "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21302/\347\272\277\347\250\213\347\273\210\346\255\242\347\232\204\345\207\240\347\247\215\346\226\271\345\274\217/GracefulShutDownThread.java" "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/\347\272\277\347\250\213\347\273\210\346\255\242\347\232\204\345\207\240\347\247\215\346\226\271\345\274\217/GracefulShutDownThread.java" similarity index 93% rename from "src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21302/\347\272\277\347\250\213\347\273\210\346\255\242\347\232\204\345\207\240\347\247\215\346\226\271\345\274\217/GracefulShutDownThread.java" rename to "src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/\347\272\277\347\250\213\347\273\210\346\255\242\347\232\204\345\207\240\347\247\215\346\226\271\345\274\217/GracefulShutDownThread.java" index a80fdabf9508905c50de30de18eddaba105dd146..75951660e152c52bf934f098b887bc2d9b08a75b 100644 --- "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21302/\347\272\277\347\250\213\347\273\210\346\255\242\347\232\204\345\207\240\347\247\215\346\226\271\345\274\217/GracefulShutDownThread.java" +++ "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/\347\272\277\347\250\213\347\273\210\346\255\242\347\232\204\345\207\240\347\247\215\346\226\271\345\274\217/GracefulShutDownThread.java" @@ -1,4 +1,4 @@ -package 并发编程02.线程终止的几种方式; +package 并发编程.demo.线程终止的几种方式; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; diff --git "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21302/\347\272\277\347\250\213\347\273\210\346\255\242\347\232\204\345\207\240\347\247\215\346\226\271\345\274\217/InterruptThread.java" "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/\347\272\277\347\250\213\347\273\210\346\255\242\347\232\204\345\207\240\347\247\215\346\226\271\345\274\217/InterruptThread.java" similarity index 98% rename from "src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21302/\347\272\277\347\250\213\347\273\210\346\255\242\347\232\204\345\207\240\347\247\215\346\226\271\345\274\217/InterruptThread.java" rename to "src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/\347\272\277\347\250\213\347\273\210\346\255\242\347\232\204\345\207\240\347\247\215\346\226\271\345\274\217/InterruptThread.java" index 59df3585e9c5358bff7c01feafb04049031821d7..dafc9b5bc58c90fc07acc298f7f91a84091199b6 100644 --- "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21302/\347\272\277\347\250\213\347\273\210\346\255\242\347\232\204\345\207\240\347\247\215\346\226\271\345\274\217/InterruptThread.java" +++ "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/\347\272\277\347\250\213\347\273\210\346\255\242\347\232\204\345\207\240\347\247\215\346\226\271\345\274\217/InterruptThread.java" @@ -1,4 +1,4 @@ -package 并发编程02.线程终止的几种方式; +package 并发编程.demo.线程终止的几种方式; import java.util.concurrent.locks.ReentrantLock; diff --git "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21302/\347\272\277\347\250\213\347\273\210\346\255\242\347\232\204\345\207\240\347\247\215\346\226\271\345\274\217/StopThread.java" "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/\347\272\277\347\250\213\347\273\210\346\255\242\347\232\204\345\207\240\347\247\215\346\226\271\345\274\217/StopThread.java" similarity index 97% rename from "src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21302/\347\272\277\347\250\213\347\273\210\346\255\242\347\232\204\345\207\240\347\247\215\346\226\271\345\274\217/StopThread.java" rename to "src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/\347\272\277\347\250\213\347\273\210\346\255\242\347\232\204\345\207\240\347\247\215\346\226\271\345\274\217/StopThread.java" index 8c782da4c7da6c7990242aa4e4eca16e99d98df7..9d62dec54d0ab9ba10d67e80219c4a48c875c171 100644 --- "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21302/\347\272\277\347\250\213\347\273\210\346\255\242\347\232\204\345\207\240\347\247\215\346\226\271\345\274\217/StopThread.java" +++ "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/\347\272\277\347\250\213\347\273\210\346\255\242\347\232\204\345\207\240\347\247\215\346\226\271\345\274\217/StopThread.java" @@ -1,4 +1,4 @@ -package 并发编程02.线程终止的几种方式; +package 并发编程.demo.线程终止的几种方式; import java.util.concurrent.locks.ReentrantLock; diff --git "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21302/\347\272\277\347\250\213\347\273\210\346\255\242\347\232\204\345\207\240\347\247\215\346\226\271\345\274\217/StopTransferThreadDemo.java" "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/\347\272\277\347\250\213\347\273\210\346\255\242\347\232\204\345\207\240\347\247\215\346\226\271\345\274\217/StopTransferThreadDemo.java" similarity index 97% rename from "src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21302/\347\272\277\347\250\213\347\273\210\346\255\242\347\232\204\345\207\240\347\247\215\346\226\271\345\274\217/StopTransferThreadDemo.java" rename to "src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/\347\272\277\347\250\213\347\273\210\346\255\242\347\232\204\345\207\240\347\247\215\346\226\271\345\274\217/StopTransferThreadDemo.java" index bd8b984159c325e05e77b03eb7d67fa2c691137f..4954f89815b5664cf46c99d1eaeed662673d9344 100644 --- "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21302/\347\272\277\347\250\213\347\273\210\346\255\242\347\232\204\345\207\240\347\247\215\346\226\271\345\274\217/StopTransferThreadDemo.java" +++ "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/\347\272\277\347\250\213\347\273\210\346\255\242\347\232\204\345\207\240\347\247\215\346\226\271\345\274\217/StopTransferThreadDemo.java" @@ -1,4 +1,4 @@ -package 并发编程02.线程终止的几种方式; +package 并发编程.demo.线程终止的几种方式; /** * @Author idea diff --git "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21302/\347\272\277\347\250\213\347\273\210\346\255\242\347\232\204\345\207\240\347\247\215\346\226\271\345\274\217/ThreadSuspendDemo.java" "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/\347\272\277\347\250\213\347\273\210\346\255\242\347\232\204\345\207\240\347\247\215\346\226\271\345\274\217/ThreadSuspendDemo.java" similarity index 94% rename from "src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21302/\347\272\277\347\250\213\347\273\210\346\255\242\347\232\204\345\207\240\347\247\215\346\226\271\345\274\217/ThreadSuspendDemo.java" rename to "src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/\347\272\277\347\250\213\347\273\210\346\255\242\347\232\204\345\207\240\347\247\215\346\226\271\345\274\217/ThreadSuspendDemo.java" index 57b1618cfba4f4fdb25352d82d56f4201771e3e3..956a81a2382278a2db11347d388099d1a7cf7fdf 100644 --- "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21302/\347\272\277\347\250\213\347\273\210\346\255\242\347\232\204\345\207\240\347\247\215\346\226\271\345\274\217/ThreadSuspendDemo.java" +++ "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/\347\272\277\347\250\213\347\273\210\346\255\242\347\232\204\345\207\240\347\247\215\346\226\271\345\274\217/ThreadSuspendDemo.java" @@ -1,4 +1,4 @@ -package 并发编程02.线程终止的几种方式; +package 并发编程.demo.线程终止的几种方式; import java.util.concurrent.TimeUnit; diff --git "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21303/\350\207\252\345\267\261\345\256\236\347\216\260\344\270\200\346\212\212\351\224\201/ILock.java" "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/\350\207\252\345\267\261\345\256\236\347\216\260\344\270\200\346\212\212\351\224\201/ILock.java" similarity index 83% rename from "src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21303/\350\207\252\345\267\261\345\256\236\347\216\260\344\270\200\346\212\212\351\224\201/ILock.java" rename to "src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/\350\207\252\345\267\261\345\256\236\347\216\260\344\270\200\346\212\212\351\224\201/ILock.java" index bd238d3af6595b2a31552724d10961fcc5a0bc7b..4423fd2027ba53402d2fe7270a038d0a73fa874d 100644 --- "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21303/\350\207\252\345\267\261\345\256\236\347\216\260\344\270\200\346\212\212\351\224\201/ILock.java" +++ "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/\350\207\252\345\267\261\345\256\236\347\216\260\344\270\200\346\212\212\351\224\201/ILock.java" @@ -1,4 +1,4 @@ -package 并发编程03.自己实现一把锁; +package 并发编程.demo.自己实现一把锁; /** * @Author idea diff --git "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21303/\350\207\252\345\267\261\345\256\236\347\216\260\344\270\200\346\212\212\351\224\201/SimpleLock.java" "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/\350\207\252\345\267\261\345\256\236\347\216\260\344\270\200\346\212\212\351\224\201/SimpleLock.java" similarity index 95% rename from "src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21303/\350\207\252\345\267\261\345\256\236\347\216\260\344\270\200\346\212\212\351\224\201/SimpleLock.java" rename to "src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/\350\207\252\345\267\261\345\256\236\347\216\260\344\270\200\346\212\212\351\224\201/SimpleLock.java" index 9f1d8c1acf1d1a16099bb04a5f1c33b75308397f..bbf9e8507e01fb931ed094db7c08f2e7eb7f10bf 100644 --- "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21303/\350\207\252\345\267\261\345\256\236\347\216\260\344\270\200\346\212\212\351\224\201/SimpleLock.java" +++ "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/\350\207\252\345\267\261\345\256\236\347\216\260\344\270\200\346\212\212\351\224\201/SimpleLock.java" @@ -1,4 +1,4 @@ -package 并发编程03.自己实现一把锁; +package 并发编程.demo.自己实现一把锁; import java.util.Iterator; import java.util.concurrent.LinkedBlockingQueue; diff --git "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21304/\351\224\201\344\270\255\346\226\255\346\241\210\344\276\213/LockInterruptDemo.java" "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/\351\224\201\344\270\255\346\226\255\346\241\210\344\276\213/LockInterruptDemo.java" similarity index 98% rename from "src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21304/\351\224\201\344\270\255\346\226\255\346\241\210\344\276\213/LockInterruptDemo.java" rename to "src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/\351\224\201\344\270\255\346\226\255\346\241\210\344\276\213/LockInterruptDemo.java" index 6ed4cc98cc3d3d7929fb2fb1116c628f31a55c76..88729042f96e8e96645b37ea220d38909727512a 100644 --- "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21304/\351\224\201\344\270\255\346\226\255\346\241\210\344\276\213/LockInterruptDemo.java" +++ "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/demo/\351\224\201\344\270\255\346\226\255\346\241\210\344\276\213/LockInterruptDemo.java" @@ -1,8 +1,7 @@ -package 并发编程04.锁中断案例; +package 并发编程.demo.锁中断案例; import org.junit.jupiter.api.Test; -import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; /** diff --git "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/question/\345\271\266\345\217\221\346\211\223\345\215\260/atomic/AtomicThread.java" "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/question/\345\271\266\345\217\221\346\211\223\345\215\260/atomic/AtomicThread.java" new file mode 100644 index 0000000000000000000000000000000000000000..ae96a3025949975ef3081071d7894d90fbadb9c3 --- /dev/null +++ "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/question/\345\271\266\345\217\221\346\211\223\345\215\260/atomic/AtomicThread.java" @@ -0,0 +1,37 @@ +package 并发编程.question.并发打印.atomic; + +import java.util.concurrent.atomic.AtomicInteger; + +/** + * 使用AtomicInteger,本身保证原子性 + */ +public class AtomicThread extends Thread { + + private AtomicInteger currentCount; + private String name; + + + private static final Integer maxCount = 100; + + private static String[] chars = {"1", "2", "3"}; + + public AtomicThread(String name, AtomicInteger currentCount) { + this.name = name; + this.currentCount = currentCount; + } + + @Override + public void run() { + + while (currentCount.get() < maxCount) { + if (this.name.equals(chars[currentCount.get() % 3])) { + System.out.println(this.name); + currentCount.getAndIncrement(); + if (this.name.equals("3")) { + System.out.println("-------------------"); + } + } + + } + } +} diff --git "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/question/\345\271\266\345\217\221\346\211\223\345\215\260/atomic/Test.java" "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/question/\345\271\266\345\217\221\346\211\223\345\215\260/atomic/Test.java" new file mode 100644 index 0000000000000000000000000000000000000000..c7d6d549af107c72967b4ecf1c2e7440cb9014a3 --- /dev/null +++ "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/question/\345\271\266\345\217\221\346\211\223\345\215\260/atomic/Test.java" @@ -0,0 +1,21 @@ +package 并发编程.question.并发打印.atomic; + +import java.util.concurrent.atomic.AtomicInteger; + +/** + * @author xiazihuai + * @title Test + * @create at 2023/4/4 21:39 + * + * 总体来看,123的输出顺序是没有问题,但是这个分割线有点毛病。。并且输出的总量有时候大于maxCount。。。 + */ +public class Test { + + public static void main(String[] args) { + + AtomicInteger target = new AtomicInteger(0); + new AtomicThread("1", target).start(); + new AtomicThread("2", target).start(); + new AtomicThread("3", target).start(); + } +} diff --git "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21305/\344\272\244\346\233\277\346\211\223\345\215\260ABC/PrintAbcDemo_2.java" "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/question/\345\271\266\345\217\221\346\211\223\345\215\260/condition/PrintAbcDemo_2.java" similarity index 98% rename from "src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21305/\344\272\244\346\233\277\346\211\223\345\215\260ABC/PrintAbcDemo_2.java" rename to "src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/question/\345\271\266\345\217\221\346\211\223\345\215\260/condition/PrintAbcDemo_2.java" index 7690c7ee4035a3faaf0f9ca0169d1a8bec847720..f8813fca817a6d7ee2820dc20367f2a18325165e 100644 --- "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21305/\344\272\244\346\233\277\346\211\223\345\215\260ABC/PrintAbcDemo_2.java" +++ "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/question/\345\271\266\345\217\221\346\211\223\345\215\260/condition/PrintAbcDemo_2.java" @@ -1,4 +1,4 @@ -package 并发编程05.交替打印ABC; +package 并发编程.question.并发打印.condition; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; diff --git "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/question/\345\271\266\345\217\221\346\211\223\345\215\260/condition/PrintThread.java" "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/question/\345\271\266\345\217\221\346\211\223\345\215\260/condition/PrintThread.java" new file mode 100644 index 0000000000000000000000000000000000000000..a8967afd63e537a3a831e87f66b04d4e1e833427 --- /dev/null +++ "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/question/\345\271\266\345\217\221\346\211\223\345\215\260/condition/PrintThread.java" @@ -0,0 +1,74 @@ +package 并发编程.question.并发打印.condition; + +import java.util.concurrent.locks.Condition; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; + +/** + * 思路:使用java中的Lock, 可以通过Lock获取Condition(监听器),这个Condition可以监听注册在上面的线程对象, + * 通过await()和notifyAll()操作线程对象的状态,可以完成“选择性通知” + */ +public class PrintThread { + + private Lock lock = new ReentrantLock(); + private int flag = 1; // 控制执行哪个线程 + + private Condition condition1 = lock.newCondition(); + private Condition condition2 = lock.newCondition(); + private Condition condition3 = lock.newCondition(); + + + public void printA() { + + lock.lock(); + + try { + while (flag != 1) { + condition1.await(); + } + System.out.println(Thread.currentThread().getName() + " : 1"); + flag = 2; + condition1.signalAll(); + } catch (InterruptedException e) { + e.printStackTrace(); + } finally { + lock.unlock(); + } + + } + + public void printB() { + lock.lock(); + + try { + while (flag != 2) { + condition2.await(); + } + System.out.println(Thread.currentThread().getName() + " : 2"); + flag = 3; + condition2.signalAll(); + } catch (InterruptedException e) { + e.printStackTrace(); + } finally { + lock.unlock(); + } + } + + + public void printC() { + lock.lock(); + + try { + while (flag != 3) { + condition3.await(); + } + System.out.println(Thread.currentThread().getName() + " : 3"); + flag = 1; + condition3.signalAll(); + } catch (InterruptedException e) { + e.printStackTrace(); + } finally { + lock.unlock(); + } + } +} diff --git "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/question/\345\271\266\345\217\221\346\211\223\345\215\260/condition/Test.java" "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/question/\345\271\266\345\217\221\346\211\223\345\215\260/condition/Test.java" new file mode 100644 index 0000000000000000000000000000000000000000..1f3f7643654453637af46e0c5caacef9170d1c88 --- /dev/null +++ "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/question/\345\271\266\345\217\221\346\211\223\345\215\260/condition/Test.java" @@ -0,0 +1,20 @@ +package 并发编程.question.并发打印.condition; + +/** + * @author xiazihuai + * @title Test + * @create at 2023/4/4 21:37 + */ +public class Test { + public static void main(String[] args) { + PrintThread printThread = new PrintThread(); + + for (int i = 0; i < 10; i++) { + new Thread(() -> printThread.printA(), "A").start(); + + new Thread(() -> printThread.printB(), "B").start(); + + new Thread(() -> printThread.printC(), "C").start(); + } + } +} diff --git "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/question/\345\271\266\345\217\221\346\211\223\345\215\260/jmm_thread/PrintThreadByFlag.java" "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/question/\345\271\266\345\217\221\346\211\223\345\215\260/jmm_thread/PrintThreadByFlag.java" new file mode 100644 index 0000000000000000000000000000000000000000..3553ba665492a811f06d2089ce53ef2743ef90a7 --- /dev/null +++ "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/question/\345\271\266\345\217\221\346\211\223\345\215\260/jmm_thread/PrintThreadByFlag.java" @@ -0,0 +1,53 @@ +package 并发编程.question.并发打印.jmm_thread; + +/** + * 由于线程的循环打印,很大程度遇到的是并发问题,而对于JMM的应对措施主要针对 原子性,可见性,指令重排; + * 想到上面这三点,第一想法是处理懒汉式单例模式的双重检测,所以写了下面这种方式: + */ +public class PrintThreadByFlag { + + private volatile int flag = 1; + + + public void printA() { + + while (true) { + if (flag == 1) { + synchronized (this) { + if (flag == 1) { + System.out.println(Thread.currentThread().getName() + ": 1"); + flag = 2; + } + } + } + } + + } + + public void printB() { + while (true) { + if (flag == 2) { + synchronized (this) { + if (flag == 2) { + System.out.println(Thread.currentThread().getName() + ": 2"); + flag = 3; + } + } + } + } + } + + public void printC() { + while (true) { + if (flag == 3) { + synchronized (this) { + if (flag == 3) { + System.out.println(Thread.currentThread().getName() + ": 3"); + System.out.println("-----------------------------------"); + flag = 1; + } + } + } + } + } +} diff --git "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/question/\345\271\266\345\217\221\346\211\223\345\215\260/jmm_thread/Test.java" "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/question/\345\271\266\345\217\221\346\211\223\345\215\260/jmm_thread/Test.java" new file mode 100644 index 0000000000000000000000000000000000000000..987f692742c378cb8a9fd68532d4ffd5ee571fbc --- /dev/null +++ "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/question/\345\271\266\345\217\221\346\211\223\345\215\260/jmm_thread/Test.java" @@ -0,0 +1,18 @@ +package 并发编程.question.并发打印.jmm_thread; + +/** + * @author xiazihuai + * @title Test + * @create at 2023/4/4 21:38 + */ +public class Test { + public static void main(String[] args) { + PrintThreadByFlag printThreadByFlag = new PrintThreadByFlag(); + + new Thread(() -> printThreadByFlag.printA(), "A").start(); + + new Thread(() -> printThreadByFlag.printB(), "B").start(); + + new Thread(() -> printThreadByFlag.printC(), "C").start(); + } +} diff --git "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21305/\344\272\244\346\233\277\346\211\223\345\215\260ABC/PrintAbcDemo_1.java" "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/question/\345\271\266\345\217\221\346\211\223\345\215\260/wait_notify/PrintAbcDemo_1.java" similarity index 97% rename from "src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21305/\344\272\244\346\233\277\346\211\223\345\215\260ABC/PrintAbcDemo_1.java" rename to "src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/question/\345\271\266\345\217\221\346\211\223\345\215\260/wait_notify/PrintAbcDemo_1.java" index a459803acd916b322197e160832076b8a6de3495..b7a6dd87ef86cd0719ec83f9780575e8bf8c19af 100644 --- "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21305/\344\272\244\346\233\277\346\211\223\345\215\260ABC/PrintAbcDemo_1.java" +++ "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/question/\345\271\266\345\217\221\346\211\223\345\215\260/wait_notify/PrintAbcDemo_1.java" @@ -1,4 +1,4 @@ -package 并发编程05.交替打印ABC; +package 并发编程.question.并发打印.wait_notify; /** * 多线程间的通信 diff --git "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/question/\347\224\237\344\272\247\350\200\205\346\266\210\350\264\271\350\200\205/await_signal/MyCacheResources2.java" "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/question/\347\224\237\344\272\247\350\200\205\346\266\210\350\264\271\350\200\205/await_signal/MyCacheResources2.java" new file mode 100644 index 0000000000000000000000000000000000000000..6552dfb82801be9512535861487144082d93d660 --- /dev/null +++ "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/question/\347\224\237\344\272\247\350\200\205\346\266\210\350\264\271\350\200\205/await_signal/MyCacheResources2.java" @@ -0,0 +1,59 @@ +package 并发编程.question.生产者消费者.await_signal; + +import java.util.concurrent.locks.Condition; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; + +//定义资源类 +class MyCacheResources2 { + int num = 0;//共享资源:生产和消费数字 + //资源池中实际存储的数据个数 + private int count = 0; + //资源池中允许存放的资源数目 + private int capacity = 5; + //创建可重入的非公平锁 + Lock lock = new ReentrantLock(); + //使用两个条件队列condition来实现精确通知 + Condition productCondition = lock.newCondition(); + Condition consumerCondition = lock.newCondition(); + + //定义操作资源类的方法:生产方法 + public void product() throws InterruptedException { + lock.lock();//加锁 + try { + //1.判断什么时候等待,并防止虚假唤醒 + while (count == capacity) {//当达到最大容量,则阻塞等待,生产者阻塞 + productCondition.await(); + } + //2.干活 + num++;//共享资源+1 + count++;//元素实际个数+1 + System.out.println(Thread.currentThread().getName() + + "\t 生产了一个数字:" + num + ",现在资源池剩余数据个数:" + count); + //3.通知。生产者生产完立马通知消费者来消费 + consumerCondition.signal();//消费者条件队列被唤醒 + } finally { + lock.unlock();//解锁 + } + } + + //定义操作资源类的方法:生产方法 + public void consumer() throws InterruptedException { + lock.lock();//加锁,同一把锁 + try { + //1.判断什么时候等待,并防止虚假唤醒 + while (count == 0) {//没数据时,则阻塞等待,消费者阻塞 + consumerCondition.await(); + } + //2.干活 + //共享资源-1 + count--;//元素实际个数-1 + System.out.println(Thread.currentThread().getName() + + "\t 消费了一个数字:" + (num--) + ",现在资源池剩余数据个数:" + count); + //3.通知。消费者 消费完 立马通知生产者来生产 + productCondition.signal();//生产者条件队列被唤醒 + } finally { + lock.unlock();//解锁 + } + } +} \ No newline at end of file diff --git "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/question/\347\224\237\344\272\247\350\200\205\346\266\210\350\264\271\350\200\205/await_signal/ProductAndConsumerTest2.java" "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/question/\347\224\237\344\272\247\350\200\205\346\266\210\350\264\271\350\200\205/await_signal/ProductAndConsumerTest2.java" new file mode 100644 index 0000000000000000000000000000000000000000..4c40e9b4e5fbb3583e94fa6b1596ec00a43fc32a --- /dev/null +++ "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/question/\347\224\237\344\272\247\350\200\205\346\266\210\350\264\271\350\200\205/await_signal/ProductAndConsumerTest2.java" @@ -0,0 +1,32 @@ +package 并发编程.question.生产者消费者.await_signal; +import java.util.concurrent.TimeUnit; + + +public class ProductAndConsumerTest2 { + public static void main(String[] args) { + MyCacheResources2 myCacheResources2 = new MyCacheResources2(); + //可以定义多个生产者和消费者,这里分别定义了一个 + new Thread(()->{ + for (int i = 0; i < 10; i++) {//10轮生产 + try { + try { TimeUnit.SECONDS.sleep(1);}//让生产者 先 生产 + catch (InterruptedException e) {e.printStackTrace();} + myCacheResources2.product(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + },"生产者").start(); + + new Thread(()->{ + for (int i = 0; i < 10; i++) {//10轮消费 + try { + myCacheResources2.consumer(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + },"消费者").start(); + } +} + diff --git "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/question/\347\224\237\344\272\247\350\200\205\346\266\210\350\264\271\350\200\205/blocking_queue/BlockQueueDemo2.java" "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/question/\347\224\237\344\272\247\350\200\205\346\266\210\350\264\271\350\200\205/blocking_queue/BlockQueueDemo2.java" new file mode 100644 index 0000000000000000000000000000000000000000..56a219c5366d86b521e3d9e6be706f8db44214fa --- /dev/null +++ "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/question/\347\224\237\344\272\247\350\200\205\346\266\210\350\264\271\350\200\205/blocking_queue/BlockQueueDemo2.java" @@ -0,0 +1,32 @@ +package 并发编程.question.生产者消费者.blocking_queue; + + +//使用阻塞队列BlockingQueue解决生产者消费者 +public class BlockQueueDemo2 { + public static void main(String[] args) { + MyResource3 myResource3 = new MyResource3(); + //这里可以通过for循环的次数控制生产者和消费者的比例,来模拟缓存区的缓存剩余情况 + for (int i = 1; i <= 5; i++) {//请变换生产者和消费者数量进行测试 + //模拟两个生产者线程 + new Thread(() -> { + while (true) {//循环生产 + try { + myResource3.add();//生产数据 + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + }, String.valueOf(i)).start(); + } + + for (int i = 1; i <= 2; i++) {//5个消费者 + new Thread(() -> { + while (true) {//循环消费 + myResource3.remove(); + } + }, String.valueOf(i)).start(); + } + } +} + + diff --git "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/question/\347\224\237\344\272\247\350\200\205\346\266\210\350\264\271\350\200\205/blocking_queue/MyResource3.java" "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/question/\347\224\237\344\272\247\350\200\205\346\266\210\350\264\271\350\200\205/blocking_queue/MyResource3.java" new file mode 100644 index 0000000000000000000000000000000000000000..39a50295df6d175ac62b236457c581d3d7b7729b --- /dev/null +++ "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/question/\347\224\237\344\272\247\350\200\205\346\266\210\350\264\271\350\200\205/blocking_queue/MyResource3.java" @@ -0,0 +1,41 @@ +package 并发编程.question.生产者消费者.blocking_queue; + +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.TimeUnit; + +/** + * 资源类 + */ +class MyResource3{ + private BlockingQueue blockingQueue = new ArrayBlockingQueue(3); + //线程操作资源类 + //向资源池中添加资源 + public void add() throws InterruptedException { + try { + //put自带锁和通知唤醒方法 + try { TimeUnit.SECONDS.sleep(1);}//模拟生产耗时1秒 + catch (InterruptedException e) {e.printStackTrace();} + //put方法是自带锁的阻塞唤醒方法,不需要我们写锁,通知和唤醒 + blockingQueue.put(1); + System.out.println("生产者"+Thread.currentThread().getName()+ + "生产一件资源,当前资源池有"+blockingQueue.size()+"个资源"); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + + //向资源池中移除资源 + public void remove(){ + try { + try { TimeUnit.SECONDS.sleep(1);}//模拟消费耗时1秒 + catch (InterruptedException e) {e.printStackTrace();} + Object take = blockingQueue.take();//自带锁和通知唤醒方法 + System.out.println("消费者" + Thread.currentThread().getName() + + "消耗一件资源," + "当前资源池有" + blockingQueue.size() + + "个资源"); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } +} \ No newline at end of file diff --git "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/question/\347\224\237\344\272\247\350\200\205\346\266\210\350\264\271\350\200\205/wait_notify/MyCacheResources1.java" "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/question/\347\224\237\344\272\247\350\200\205\346\266\210\350\264\271\350\200\205/wait_notify/MyCacheResources1.java" new file mode 100644 index 0000000000000000000000000000000000000000..9fd56c72855d6341720b01184f4026947151c8fe --- /dev/null +++ "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/question/\347\224\237\344\272\247\350\200\205\346\266\210\350\264\271\350\200\205/wait_notify/MyCacheResources1.java" @@ -0,0 +1,47 @@ +package 并发编程.question.生产者消费者.wait_notify; + +//1.定义资源类 +class MyCacheResources1 { + int num = 0;//共享资源:生产和消费数字 + //资源池中实际存储的数据个数 + private int count = 0; + //资源池中允许存放的资源数目 + private int capacity = 5; + + Object obj = new Object();//作为锁 + + //生产方法 + public void product() throws InterruptedException { + //使用代码块,精确加锁,且synchronized会自动释放锁 + synchronized (obj) { + //1.判断什么时候等待 + if (count == capacity) {//当实际元素数量达到总容量是,生产阻塞等待 + obj.wait(); + } + //2.干活 + num++; + count++;//生产一个数字,元素数量+1 + System.out.println(Thread.currentThread().getName() + + "生产了一个数字" + num + ",资源池剩余数据个数:" + count); + //3.干完后后通知唤醒 消费者来消费 + obj.notifyAll();//唤醒其他所有线程,让他们竞争锁 + } + } + + //消费的方法 + public void consumer() throws InterruptedException { + synchronized (obj) { + //1.判断什么时候等待 + if (count == 0) {//当实际元素数量达到总容量是,生产阻塞等待 + obj.wait(); + } + //2.干活 + num--; + count--;//消费一个元素,数量-1 + System.out.println(Thread.currentThread().getName() + + "消费了一个数字" + num + ",资源池剩余数据个数:" + count); + //3.干完后后通知唤醒 生产者 + obj.notifyAll();//唤醒其他所有线程,让他们竞争锁 + } + } +} \ No newline at end of file diff --git "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/question/\347\224\237\344\272\247\350\200\205\346\266\210\350\264\271\350\200\205/wait_notify/ProductAndConsumerTest1.java" "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/question/\347\224\237\344\272\247\350\200\205\346\266\210\350\264\271\350\200\205/wait_notify/ProductAndConsumerTest1.java" new file mode 100644 index 0000000000000000000000000000000000000000..9e2f4f77ea74cbe0cde00377b6fdcc1ad0021314 --- /dev/null +++ "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/question/\347\224\237\344\272\247\350\200\205\346\266\210\350\264\271\350\200\205/wait_notify/ProductAndConsumerTest1.java" @@ -0,0 +1,60 @@ +package 并发编程.question.生产者消费者.wait_notify; + +import java.util.concurrent.TimeUnit; + +/** + * 使用 synchronized 和 wait、notify 实现生产者和消费者 + */ +public class ProductAndConsumerTest1 { + + public static void main(String[] args) { + MyCacheResources1 myCacheResources1 = new MyCacheResources1(); + //这里我们直接使用匿名内部类的变相lamda表达式来创建线程 + //生产者 + new Thread(() -> { + for (int i = 1; i <= 10; i++) {//生产10轮 + try { + myCacheResources1.product(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + + }, "生产者").start(); + + //消费者 + new Thread(() -> { + //让生产者先 生产数据 + for (int i = 1; i <= 10; i++) {//消费10轮, + try { + TimeUnit.SECONDS.sleep(1); + } catch (InterruptedException e) { + e.printStackTrace(); + } + try { + myCacheResources1.consumer(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + }, "消费者1").start(); + + new Thread(() -> { + //让生产者先 生产数据 + for (int i = 1; i <= 10; i++) {//消费10轮, + try { + TimeUnit.SECONDS.sleep(1); + } catch (InterruptedException e) { + e.printStackTrace(); + } + try { + myCacheResources1.consumer(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + }, "消费者2").start(); + + } +} + diff --git "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/question/\351\231\220\346\265\201/Counter.java" "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/question/\351\231\220\346\265\201/Counter.java" new file mode 100644 index 0000000000000000000000000000000000000000..c98e97f8056dbc0a255c14b2bbebf0a56cf346a4 --- /dev/null +++ "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/question/\351\231\220\346\265\201/Counter.java" @@ -0,0 +1,28 @@ +package 并发编程.question.限流; + +/** + * @title Counter 最简单的计数器限流算法 + * @author xiazihuai + * @create at 2023/4/12 20:37 + */ +public class Counter { + public long timeStamp = System.currentTimeMillis(); // 当前时间 + public int reqCount = 0; // 初始化计数器 + public final int limit = 100; // 时间窗口内最大请求数 + public final long interval = 1000 * 60; // 时间窗口ms + + public boolean limit() { + long now = System.currentTimeMillis(); + if (now < timeStamp + interval) { + // 在时间窗口内 + reqCount++; + // 判断当前时间窗口内是否超过最大请求控制数 + return reqCount <= limit; + } else { + timeStamp = now; + // 超时后重置 + reqCount = 1; + return true; + } + } +} diff --git "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/question/\351\231\220\346\265\201/LeakyBucket.java" "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/question/\351\231\220\346\265\201/LeakyBucket.java" new file mode 100644 index 0000000000000000000000000000000000000000..28e7b63507a871ed992bfcf1cf6e3d26441d33ba --- /dev/null +++ "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/question/\351\231\220\346\265\201/LeakyBucket.java" @@ -0,0 +1,27 @@ +package 并发编程.question.限流; + +/** + * @author xiazihuai + * @title LeakyBucket 漏桶限流算法 + * @create at 2023/4/12 20:39 + */ +public class LeakyBucket { + public long timeStamp = System.currentTimeMillis(); // 当前时间 + public long capacity; // 桶的容量 + public long rate; // 水漏出的速度(每秒系统能处理的请求数) + public long water; // 当前水量(当前累积请求数) + + public boolean limit() { + long now = System.currentTimeMillis(); + water = Math.max(0, water - ((now - timeStamp) / 1000) * rate); // 先执行漏水,计算剩余水量 + timeStamp = now; + if ((water + 1) < capacity) { + // 尝试加水,并且水还未满 + water += 1; + return true; + } else { + // 水满,拒绝加水 + return false; + } + } +} diff --git "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/question/\351\231\220\346\265\201/SlidingTimeWindow.java" "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/question/\351\231\220\346\265\201/SlidingTimeWindow.java" new file mode 100644 index 0000000000000000000000000000000000000000..39bee1d3906da82a1e8f970e6c772f46f932d787 --- /dev/null +++ "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/question/\351\231\220\346\265\201/SlidingTimeWindow.java" @@ -0,0 +1,57 @@ +package 并发编程.question.限流; + +import java.util.LinkedList; +import java.util.Random; + +/** + * @title 滑动时间窗口限流实现 + * 假设某个服务最多只能每秒钟处理100个请求,我们可以设置一个1秒钟的滑动时间窗口, + * 窗口中有10个格子,每个格子100毫秒,每100毫秒移动一次,每次移动都需要记录当前服务请求的次数 + * @author xiazihuai + * @create at 2023/4/12 20:38 + */ +public class SlidingTimeWindow { + //服务访问次数,可以放在Redis中,实现分布式系统的访问计数 + Long counter = 0L; + //使用LinkedList来记录滑动窗口的10个格子。 + LinkedList slots = new LinkedList(); + + public static void main(String[] args) throws InterruptedException { + SlidingTimeWindow timeWindow = new SlidingTimeWindow(); + + new Thread(new Runnable() { + @Override + public void run() { + try { + timeWindow.doCheck(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + }).start(); + + while (true){ + //TODO 判断限流标记 + timeWindow.counter++; + Thread.sleep(new Random().nextInt(15)); + } + } + + private void doCheck() throws InterruptedException { + while (true) { + slots.addLast(counter); + if (slots.size() > 10) { + slots.removeFirst(); + } + //比较最后一个和第一个,两者相差100以上就限流 + if ((slots.peekLast() - slots.peekFirst()) > 100) { + System.out.println("限流了。。"); + //TODO 修改限流标记为true + }else { + //TODO 修改限流标记为false + } + + Thread.sleep(100); + } + } +} diff --git "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/question/\351\231\220\346\265\201/TokenBucket.java" "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/question/\351\231\220\346\265\201/TokenBucket.java" new file mode 100644 index 0000000000000000000000000000000000000000..e96fd7cc1f7899872a3c407d2325933aad97cfa2 --- /dev/null +++ "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/question/\351\231\220\346\265\201/TokenBucket.java" @@ -0,0 +1,28 @@ +package 并发编程.question.限流; + +/** + * @author xiazihuai + * @title TokenBucket 令牌桶限流算法 + * @create at 2023/4/12 20:40 + */ +public class TokenBucket { + public long timeStamp = System.currentTimeMillis(); // 当前时间 + public long capacity; // 桶的容量 + public long rate; // 令牌放入速度 + public long tokens; // 当前令牌数量 + + public boolean grant() { + long now = System.currentTimeMillis(); + // 先添加令牌 + tokens = Math.min(capacity, tokens + (now - timeStamp) * rate); + timeStamp = now; + if (tokens < 1) { + // 若不到1个令牌,则拒绝 + return false; + } else { + // 还有令牌,领取令牌 + tokens -= 1; + return true; + } + } +} diff --git "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/question/\351\231\220\346\265\201/readme.md" "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/question/\351\231\220\346\265\201/readme.md" new file mode 100644 index 0000000000000000000000000000000000000000..13f19972a80e96f40f8c3e2a0e4442c94219de23 --- /dev/null +++ "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/question/\351\231\220\346\265\201/readme.md" @@ -0,0 +1,11 @@ +限流算法小结(请结合图灵五期sentinel源码详解学习) + + 计数器 VS 滑动窗口: + 1、计数器算法是最简单的算法,可以看成是滑动窗口的低精度实现。 + 2、滑动窗口由于需要存储多份的计数器(每一个格子存一份),所以滑动窗口在实现上需要更多的存储空间。 + 3、也就是说,如果滑动窗口的精度越高,需要的存储空间就越大。 + + 漏桶算法 VS 令牌桶算法: + 1、漏桶算法和令牌桶算法最明显的区别是令牌桶算法允许流量一定程度的突发。 + 2、因为默认的令牌桶算法,取走token是不需要耗费时间的,也就是说,假设桶内有100个token时,那么可以瞬间允许100个请求通过。 + 3、当然我们需要具体情况具体分析,只有最合适的算法,没有最优的算法。 \ No newline at end of file diff --git "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21309/balking\346\250\241\345\274\217/BalkingDemo.java" "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/\350\256\276\350\256\241\346\250\241\345\274\217/balking\346\250\241\345\274\217/BalkingDemo.java" similarity index 96% rename from "src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21309/balking\346\250\241\345\274\217/BalkingDemo.java" rename to "src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/\350\256\276\350\256\241\346\250\241\345\274\217/balking\346\250\241\345\274\217/BalkingDemo.java" index f5beab2ff5702ddb7976f6e854ef86f675e15620..7ce48931421a064fd59776cd593d62421394009b 100644 --- "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21309/balking\346\250\241\345\274\217/BalkingDemo.java" +++ "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/\350\256\276\350\256\241\346\250\241\345\274\217/balking\346\250\241\345\274\217/BalkingDemo.java" @@ -1,4 +1,4 @@ -package 并发编程09.balking模式; +package 并发编程.设计模式.balking模式; /** * @Author idea diff --git "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21309/copyonwrite\346\250\241\345\274\217/CopyOnWriteDemo.java" "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/\350\256\276\350\256\241\346\250\241\345\274\217/copyonwrite\346\250\241\345\274\217/CopyOnWriteDemo.java" similarity index 94% rename from "src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21309/copyonwrite\346\250\241\345\274\217/CopyOnWriteDemo.java" rename to "src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/\350\256\276\350\256\241\346\250\241\345\274\217/copyonwrite\346\250\241\345\274\217/CopyOnWriteDemo.java" index 4d4342c1c3e023d3ac3e28b6b82e75897a3c7d04..f7d658f4af2f3f82ea6c89bacc258bc1d00d3968 100644 --- "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21309/copyonwrite\346\250\241\345\274\217/CopyOnWriteDemo.java" +++ "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/\350\256\276\350\256\241\346\250\241\345\274\217/copyonwrite\346\250\241\345\274\217/CopyOnWriteDemo.java" @@ -1,4 +1,4 @@ -package 并发编程09.copyonwrite模式; +package 并发编程.设计模式.copyonwrite模式; import org.junit.jupiter.api.Test; diff --git "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21309/guarded_suspension\346\250\241\345\274\217/MQProducer.java" "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/\350\256\276\350\256\241\346\250\241\345\274\217/guarded_suspension\346\250\241\345\274\217/MQProducer.java" similarity index 96% rename from "src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21309/guarded_suspension\346\250\241\345\274\217/MQProducer.java" rename to "src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/\350\256\276\350\256\241\346\250\241\345\274\217/guarded_suspension\346\250\241\345\274\217/MQProducer.java" index aa4dc1e0a32c28a323bfdf5070714d213001652c..fec08020d0f8140674c2d637b5180837187c752b 100644 --- "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21309/guarded_suspension\346\250\241\345\274\217/MQProducer.java" +++ "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/\350\256\276\350\256\241\346\250\241\345\274\217/guarded_suspension\346\250\241\345\274\217/MQProducer.java" @@ -1,4 +1,4 @@ -package 并发编程09.guarded_suspension模式; +package 并发编程.设计模式.guarded_suspension模式; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; diff --git "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21309/guarded_suspension\346\250\241\345\274\217/SendResult.java" "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/\350\256\276\350\256\241\346\250\241\345\274\217/guarded_suspension\346\250\241\345\274\217/SendResult.java" similarity index 77% rename from "src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21309/guarded_suspension\346\250\241\345\274\217/SendResult.java" rename to "src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/\350\256\276\350\256\241\346\250\241\345\274\217/guarded_suspension\346\250\241\345\274\217/SendResult.java" index 5b54809aad3ad90c3895d34f8eb94045659dc47a..2deb6b11845f8f433395c59135cb3400bca1fa78 100644 --- "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21309/guarded_suspension\346\250\241\345\274\217/SendResult.java" +++ "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/\350\256\276\350\256\241\346\250\241\345\274\217/guarded_suspension\346\250\241\345\274\217/SendResult.java" @@ -1,4 +1,4 @@ -package 并发编程09.guarded_suspension模式; +package 并发编程.设计模式.guarded_suspension模式; /** * @Author idea diff --git "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21309/producer_consumer\346\250\241\345\274\217/Consumer.java" "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/\350\256\276\350\256\241\346\250\241\345\274\217/producer_consumer\346\250\241\345\274\217/Consumer.java" similarity index 92% rename from "src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21309/producer_consumer\346\250\241\345\274\217/Consumer.java" rename to "src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/\350\256\276\350\256\241\346\250\241\345\274\217/producer_consumer\346\250\241\345\274\217/Consumer.java" index cc6ac1bc5e8158567968a9e14371fd60a5e43774..8666114934ee04754692ee8855e3672ce53b2ec0 100644 --- "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21309/producer_consumer\346\250\241\345\274\217/Consumer.java" +++ "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/\350\256\276\350\256\241\346\250\241\345\274\217/producer_consumer\346\250\241\345\274\217/Consumer.java" @@ -1,4 +1,4 @@ -package 并发编程09.producer_consumer模式; +package 并发编程.设计模式.producer_consumer模式; import java.util.concurrent.ArrayBlockingQueue; diff --git "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21309/producer_consumer\346\250\241\345\274\217/Producer.java" "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/\350\256\276\350\256\241\346\250\241\345\274\217/producer_consumer\346\250\241\345\274\217/Producer.java" similarity index 91% rename from "src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21309/producer_consumer\346\250\241\345\274\217/Producer.java" rename to "src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/\350\256\276\350\256\241\346\250\241\345\274\217/producer_consumer\346\250\241\345\274\217/Producer.java" index a776a87466133ddb86811b6da8b970146093c8cd..a0a9eb709e761671fb7ffd538671d29405b1ab35 100644 --- "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21309/producer_consumer\346\250\241\345\274\217/Producer.java" +++ "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/\350\256\276\350\256\241\346\250\241\345\274\217/producer_consumer\346\250\241\345\274\217/Producer.java" @@ -1,4 +1,4 @@ -package 并发编程09.producer_consumer模式; +package 并发编程.设计模式.producer_consumer模式; import java.util.concurrent.ArrayBlockingQueue; diff --git "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21309/producer_consumer\346\250\241\345\274\217/TestDemo.java" "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/\350\256\276\350\256\241\346\250\241\345\274\217/producer_consumer\346\250\241\345\274\217/TestDemo.java" similarity index 91% rename from "src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21309/producer_consumer\346\250\241\345\274\217/TestDemo.java" rename to "src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/\350\256\276\350\256\241\346\250\241\345\274\217/producer_consumer\346\250\241\345\274\217/TestDemo.java" index b5293eca5bd46e4dabf8ecdd8f69f881f5c23c49..01aada960919565666cba462705cd9d445236bd2 100644 --- "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21309/producer_consumer\346\250\241\345\274\217/TestDemo.java" +++ "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\213/\350\256\276\350\256\241\346\250\241\345\274\217/producer_consumer\346\250\241\345\274\217/TestDemo.java" @@ -1,4 +1,4 @@ -package 并发编程09.producer_consumer模式; +package 并发编程.设计模式.producer_consumer模式; import java.util.UUID; import java.util.concurrent.ArrayBlockingQueue; diff --git "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21305/wait\345\222\214notifyAll\346\241\210\344\276\213/Demo.java" "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21305/wait\345\222\214notifyAll\346\241\210\344\276\213/Demo.java" deleted file mode 100644 index 2c72aa67636abbc565f136b186332d83f914e05c..0000000000000000000000000000000000000000 --- "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21305/wait\345\222\214notifyAll\346\241\210\344\276\213/Demo.java" +++ /dev/null @@ -1,8 +0,0 @@ -package 并发编程05.wait和notifyAll案例; - -/** - * @Author idea - * @Date created in 7:58 上午 2022/6/23 - */ -public class Demo { -} diff --git "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21305/wait\345\222\214notify\346\241\210\344\276\213/SingleCommonCache.java" "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21305/wait\345\222\214notify\346\241\210\344\276\213/SingleCommonCache.java" deleted file mode 100644 index e10a4b14586714d97c6a1dc27fa65ac4991bbff4..0000000000000000000000000000000000000000 --- "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21305/wait\345\222\214notify\346\241\210\344\276\213/SingleCommonCache.java" +++ /dev/null @@ -1,25 +0,0 @@ -package 并发编程05.wait和notify案例; - - -import java.util.concurrent.locks.ReentrantLock; - -/** - * @Author idea - * @Date created in 8:51 上午 2022/6/13 - */ -public class SingleCommonCache { - - private static int size = 10; - private static Object[] MSG_QUEUE = new Object[size]; - private static int putIndex = 0; - private static int consumerIndex = 0; - - public static boolean putMsg(String msg) { - if (putIndex == size) { - System.err.println("消息队列体积已达到上限!"); - return false; - } - MSG_QUEUE[putIndex++] = msg; - return true; - } -} diff --git "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21305/wait\345\222\214notify\346\241\210\344\276\213/SingleConsumer.java" "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21305/wait\345\222\214notify\346\241\210\344\276\213/SingleConsumer.java" deleted file mode 100644 index fa85db825772fc44ce6808e157034096e7825413..0000000000000000000000000000000000000000 --- "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21305/wait\345\222\214notify\346\241\210\344\276\213/SingleConsumer.java" +++ /dev/null @@ -1,8 +0,0 @@ -package 并发编程05.wait和notify案例; - -/** - * @Author idea - * @Date created in 8:50 上午 2022/6/13 - */ -public class SingleConsumer { -} diff --git "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21305/wait\345\222\214notify\346\241\210\344\276\213/SingleProducer.java" "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21305/wait\345\222\214notify\346\241\210\344\276\213/SingleProducer.java" deleted file mode 100644 index 036d8992f98e913f88023ef7617cd5473145090e..0000000000000000000000000000000000000000 --- "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21305/wait\345\222\214notify\346\241\210\344\276\213/SingleProducer.java" +++ /dev/null @@ -1,12 +0,0 @@ -package 并发编程05.wait和notify案例; - - -/** - * @Author idea - * @Date created in 8:49 上午 2022/6/13 - */ -public class SingleProducer { - - public static void saveQueue(Integer msg){ - } -} diff --git "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21310/CountDownLatchDemo.java" "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21310/CountDownLatchDemo.java" deleted file mode 100644 index d760c3e79d26e8e8a587befe4b2ed91b6ef7aea1..0000000000000000000000000000000000000000 --- "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21310/CountDownLatchDemo.java" +++ /dev/null @@ -1,12 +0,0 @@ -package 并发编程10; - -import java.util.concurrent.CountDownLatch; - -/** - * @Author idea - * @Date created in 2:12 下午 2022/7/15 - */ -public class CountDownLatchDemo { - - -} diff --git "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21316/\345\210\206\345\270\203\345\274\217\351\224\201\346\240\270\345\277\203\345\256\236\347\216\260/config/LockInfo.java" "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21316/\345\210\206\345\270\203\345\274\217\351\224\201/\345\210\206\345\270\203\345\274\217\351\224\201\346\240\270\345\277\203\345\256\236\347\216\260/config/LockInfo.java" similarity index 79% rename from "src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21316/\345\210\206\345\270\203\345\274\217\351\224\201\346\240\270\345\277\203\345\256\236\347\216\260/config/LockInfo.java" rename to "src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21316/\345\210\206\345\270\203\345\274\217\351\224\201/\345\210\206\345\270\203\345\274\217\351\224\201\346\240\270\345\277\203\345\256\236\347\216\260/config/LockInfo.java" index 89716e81180ec25bac9d49380064bdc557950f96..8f36ed9c2accb38b2d82303dd184c7390aefae1d 100644 --- "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21316/\345\210\206\345\270\203\345\274\217\351\224\201\346\240\270\345\277\203\345\256\236\347\216\260/config/LockInfo.java" +++ "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21316/\345\210\206\345\270\203\345\274\217\351\224\201/\345\210\206\345\270\203\345\274\217\351\224\201\346\240\270\345\277\203\345\256\236\347\216\260/config/LockInfo.java" @@ -1,4 +1,4 @@ -package 并发编程16.分布式锁核心实现.config; +package 并发编程16.分布式锁.分布式锁核心实现.config; /** * @Author idea diff --git "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21316/\345\210\206\345\270\203\345\274\217\351\224\201\346\240\270\345\277\203\345\256\236\347\216\260/config/RedisInitConfiguration.java" "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21316/\345\210\206\345\270\203\345\274\217\351\224\201/\345\210\206\345\270\203\345\274\217\351\224\201\346\240\270\345\277\203\345\256\236\347\216\260/config/RedisInitConfiguration.java" similarity index 74% rename from "src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21316/\345\210\206\345\270\203\345\274\217\351\224\201\346\240\270\345\277\203\345\256\236\347\216\260/config/RedisInitConfiguration.java" rename to "src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21316/\345\210\206\345\270\203\345\274\217\351\224\201/\345\210\206\345\270\203\345\274\217\351\224\201\346\240\270\345\277\203\345\256\236\347\216\260/config/RedisInitConfiguration.java" index e494af1378a923439eaf48947b733846a9265aa6..63f5ab91666c71ea0d7048f54df22cf63e1f5a09 100644 --- "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21316/\345\210\206\345\270\203\345\274\217\351\224\201\346\240\270\345\277\203\345\256\236\347\216\260/config/RedisInitConfiguration.java" +++ "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21316/\345\210\206\345\270\203\345\274\217\351\224\201/\345\210\206\345\270\203\345\274\217\351\224\201\346\240\270\345\277\203\345\256\236\347\216\260/config/RedisInitConfiguration.java" @@ -1,4 +1,4 @@ -package 并发编程16.分布式锁核心实现.config; +package 并发编程16.分布式锁.分布式锁核心实现.config; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -8,12 +8,12 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import 并发编程16.分布式锁核心实现.lock.IDistributionLock; -import 并发编程16.分布式锁核心实现.lock.impl.DistributionLock; -import 并发编程16.分布式锁核心实现.redis.IRedisFactory; -import 并发编程16.分布式锁核心实现.redis.IRedisService; -import 并发编程16.分布式锁核心实现.redis.impl.RedisFactoryImpl; -import 并发编程16.分布式锁核心实现.redis.impl.RedisServiceImpl; +import 并发编程16.分布式锁.分布式锁核心实现.lock.IDistributionLock; +import 并发编程16.分布式锁.分布式锁核心实现.lock.impl.DistributionLock; +import 并发编程16.分布式锁.分布式锁核心实现.redis.impl.RedisFactoryImpl; +import 并发编程16.分布式锁.分布式锁核心实现.redis.IRedisFactory; +import 并发编程16.分布式锁.分布式锁核心实现.redis.IRedisService; +import 并发编程16.分布式锁.分布式锁核心实现.redis.impl.RedisServiceImpl; import javax.annotation.Resource; diff --git "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21316/\345\210\206\345\270\203\345\274\217\351\224\201\346\240\270\345\277\203\345\256\236\347\216\260/config/RedisProperties.java" "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21316/\345\210\206\345\270\203\345\274\217\351\224\201/\345\210\206\345\270\203\345\274\217\351\224\201\346\240\270\345\277\203\345\256\236\347\216\260/config/RedisProperties.java" similarity index 97% rename from "src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21316/\345\210\206\345\270\203\345\274\217\351\224\201\346\240\270\345\277\203\345\256\236\347\216\260/config/RedisProperties.java" rename to "src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21316/\345\210\206\345\270\203\345\274\217\351\224\201/\345\210\206\345\270\203\345\274\217\351\224\201\346\240\270\345\277\203\345\256\236\347\216\260/config/RedisProperties.java" index 1f58cca74b299e7eda4ea465d9bb4500450185fd..3adc155666b2eb200b0fce08f7f7646a1d419e92 100644 --- "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21316/\345\210\206\345\270\203\345\274\217\351\224\201\346\240\270\345\277\203\345\256\236\347\216\260/config/RedisProperties.java" +++ "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21316/\345\210\206\345\270\203\345\274\217\351\224\201/\345\210\206\345\270\203\345\274\217\351\224\201\346\240\270\345\277\203\345\256\236\347\216\260/config/RedisProperties.java" @@ -1,4 +1,4 @@ -package 并发编程16.分布式锁核心实现.config; +package 并发编程16.分布式锁.分布式锁核心实现.config; import org.springframework.boot.context.properties.ConfigurationProperties; diff --git "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21316/\345\210\206\345\270\203\345\274\217\351\224\201\346\240\270\345\277\203\345\256\236\347\216\260/lock/IDistributionLock.java" "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21316/\345\210\206\345\270\203\345\274\217\351\224\201/\345\210\206\345\270\203\345\274\217\351\224\201\346\240\270\345\277\203\345\256\236\347\216\260/lock/IDistributionLock.java" similarity index 90% rename from "src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21316/\345\210\206\345\270\203\345\274\217\351\224\201\346\240\270\345\277\203\345\256\236\347\216\260/lock/IDistributionLock.java" rename to "src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21316/\345\210\206\345\270\203\345\274\217\351\224\201/\345\210\206\345\270\203\345\274\217\351\224\201\346\240\270\345\277\203\345\256\236\347\216\260/lock/IDistributionLock.java" index 00d41171519a688e6b5103d83add852932db1a6a..c9c4b5fcb0437d47b61b5b74f7dc1aae46f4dec6 100644 --- "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21316/\345\210\206\345\270\203\345\274\217\351\224\201\346\240\270\345\277\203\345\256\236\347\216\260/lock/IDistributionLock.java" +++ "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21316/\345\210\206\345\270\203\345\274\217\351\224\201/\345\210\206\345\270\203\345\274\217\351\224\201\346\240\270\345\277\203\345\256\236\347\216\260/lock/IDistributionLock.java" @@ -1,4 +1,4 @@ -package 并发编程16.分布式锁核心实现.lock; +package 并发编程16.分布式锁.分布式锁核心实现.lock; /** * @Author idea diff --git "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21316/\345\210\206\345\270\203\345\274\217\351\224\201\346\240\270\345\277\203\345\256\236\347\216\260/lock/LockStatusThreadLock.java" "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21316/\345\210\206\345\270\203\345\274\217\351\224\201/\345\210\206\345\270\203\345\274\217\351\224\201\346\240\270\345\277\203\345\256\236\347\216\260/lock/LockStatusThreadLock.java" similarity index 80% rename from "src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21316/\345\210\206\345\270\203\345\274\217\351\224\201\346\240\270\345\277\203\345\256\236\347\216\260/lock/LockStatusThreadLock.java" rename to "src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21316/\345\210\206\345\270\203\345\274\217\351\224\201/\345\210\206\345\270\203\345\274\217\351\224\201\346\240\270\345\277\203\345\256\236\347\216\260/lock/LockStatusThreadLock.java" index f994af0c5e9871181d727b96d67c3a3c4a8181c7..8456cb4d8da182f1be79c98815fe8a7fcb8a8c8c 100644 --- "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21316/\345\210\206\345\270\203\345\274\217\351\224\201\346\240\270\345\277\203\345\256\236\347\216\260/lock/LockStatusThreadLock.java" +++ "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21316/\345\210\206\345\270\203\345\274\217\351\224\201/\345\210\206\345\270\203\345\274\217\351\224\201\346\240\270\345\277\203\345\256\236\347\216\260/lock/LockStatusThreadLock.java" @@ -1,4 +1,4 @@ -package 并发编程16.分布式锁核心实现.lock; +package 并发编程16.分布式锁.分布式锁核心实现.lock; import com.alibaba.ttl.TransmittableThreadLocal; diff --git "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21316/\345\210\206\345\270\203\345\274\217\351\224\201\346\240\270\345\277\203\345\256\236\347\216\260/lock/impl/DistributionLock.java" "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21316/\345\210\206\345\270\203\345\274\217\351\224\201/\345\210\206\345\270\203\345\274\217\351\224\201\346\240\270\345\277\203\345\256\236\347\216\260/lock/impl/DistributionLock.java" similarity index 93% rename from "src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21316/\345\210\206\345\270\203\345\274\217\351\224\201\346\240\270\345\277\203\345\256\236\347\216\260/lock/impl/DistributionLock.java" rename to "src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21316/\345\210\206\345\270\203\345\274\217\351\224\201/\345\210\206\345\270\203\345\274\217\351\224\201\346\240\270\345\277\203\345\256\236\347\216\260/lock/impl/DistributionLock.java" index ceb5121b771c10574babca3881f18398c8007372..a98b07d874988eb5c5fa16eaf708043f3e12ab47 100644 --- "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21316/\345\210\206\345\270\203\345\274\217\351\224\201\346\240\270\345\277\203\345\256\236\347\216\260/lock/impl/DistributionLock.java" +++ "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21316/\345\210\206\345\270\203\345\274\217\351\224\201/\345\210\206\345\270\203\345\274\217\351\224\201\346\240\270\345\277\203\345\256\236\347\216\260/lock/impl/DistributionLock.java" @@ -1,10 +1,10 @@ -package 并发编程16.分布式锁核心实现.lock.impl; +package 并发编程16.分布式锁.分布式锁核心实现.lock.impl; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import 并发编程16.分布式锁核心实现.lock.IDistributionLock; -import 并发编程16.分布式锁核心实现.lock.LockStatusThreadLock; -import 并发编程16.分布式锁核心实现.redis.IRedisService; +import 并发编程16.分布式锁.分布式锁核心实现.lock.IDistributionLock; +import 并发编程16.分布式锁.分布式锁核心实现.lock.LockStatusThreadLock; +import 并发编程16.分布式锁.分布式锁核心实现.redis.IRedisService; import java.util.HashSet; import java.util.Set; diff --git "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21316/\345\210\206\345\270\203\345\274\217\351\224\201\346\240\270\345\277\203\345\256\236\347\216\260/redis/IRedisFactory.java" "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21316/\345\210\206\345\270\203\345\274\217\351\224\201/\345\210\206\345\270\203\345\274\217\351\224\201\346\240\270\345\277\203\345\256\236\347\216\260/redis/IRedisFactory.java" similarity index 76% rename from "src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21316/\345\210\206\345\270\203\345\274\217\351\224\201\346\240\270\345\277\203\345\256\236\347\216\260/redis/IRedisFactory.java" rename to "src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21316/\345\210\206\345\270\203\345\274\217\351\224\201/\345\210\206\345\270\203\345\274\217\351\224\201\346\240\270\345\277\203\345\256\236\347\216\260/redis/IRedisFactory.java" index d90180353999655ee55ff98087aaaa12e1591fcc..6f87c7a212354144f3ea6430b9010f36b174d16b 100644 --- "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21316/\345\210\206\345\270\203\345\274\217\351\224\201\346\240\270\345\277\203\345\256\236\347\216\260/redis/IRedisFactory.java" +++ "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21316/\345\210\206\345\270\203\345\274\217\351\224\201/\345\210\206\345\270\203\345\274\217\351\224\201\346\240\270\345\277\203\345\256\236\347\216\260/redis/IRedisFactory.java" @@ -1,8 +1,8 @@ -package 并发编程16.分布式锁核心实现.redis; +package 并发编程16.分布式锁.分布式锁核心实现.redis; import redis.clients.jedis.Jedis; import redis.clients.jedis.JedisPool; -import 并发编程16.分布式锁核心实现.config.RedisProperties; +import 并发编程16.分布式锁.分布式锁核心实现.config.RedisProperties; /** * 只处理jedis的创建,销毁工作 diff --git "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21316/\345\210\206\345\270\203\345\274\217\351\224\201\346\240\270\345\277\203\345\256\236\347\216\260/redis/IRedisService.java" "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21316/\345\210\206\345\270\203\345\274\217\351\224\201/\345\210\206\345\270\203\345\274\217\351\224\201\346\240\270\345\277\203\345\256\236\347\216\260/redis/IRedisService.java" similarity index 94% rename from "src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21316/\345\210\206\345\270\203\345\274\217\351\224\201\346\240\270\345\277\203\345\256\236\347\216\260/redis/IRedisService.java" rename to "src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21316/\345\210\206\345\270\203\345\274\217\351\224\201/\345\210\206\345\270\203\345\274\217\351\224\201\346\240\270\345\277\203\345\256\236\347\216\260/redis/IRedisService.java" index 3aa97b76bf7d8bf50d6fc8489c6ca02ef3a4fbcb..4066c371c3fade6e3f5f01b4e384d98830dc2f07 100644 --- "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21316/\345\210\206\345\270\203\345\274\217\351\224\201\346\240\270\345\277\203\345\256\236\347\216\260/redis/IRedisService.java" +++ "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21316/\345\210\206\345\270\203\345\274\217\351\224\201/\345\210\206\345\270\203\345\274\217\351\224\201\346\240\270\345\277\203\345\256\236\347\216\260/redis/IRedisService.java" @@ -1,4 +1,4 @@ -package 并发编程16.分布式锁核心实现.redis; +package 并发编程16.分布式锁.分布式锁核心实现.redis; import java.util.List; diff --git "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21316/\345\210\206\345\270\203\345\274\217\351\224\201\346\240\270\345\277\203\345\256\236\347\216\260/redis/impl/RedisFactoryImpl.java" "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21316/\345\210\206\345\270\203\345\274\217\351\224\201/\345\210\206\345\270\203\345\274\217\351\224\201\346\240\270\345\277\203\345\256\236\347\216\260/redis/impl/RedisFactoryImpl.java" similarity index 89% rename from "src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21316/\345\210\206\345\270\203\345\274\217\351\224\201\346\240\270\345\277\203\345\256\236\347\216\260/redis/impl/RedisFactoryImpl.java" rename to "src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21316/\345\210\206\345\270\203\345\274\217\351\224\201/\345\210\206\345\270\203\345\274\217\351\224\201\346\240\270\345\277\203\345\256\236\347\216\260/redis/impl/RedisFactoryImpl.java" index 9f3b9e0aa7858338eab4fb98012b27e423ee4583..15bfeb9d1c502fa3751d88324fe5d5fba4d91f0b 100644 --- "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21316/\345\210\206\345\270\203\345\274\217\351\224\201\346\240\270\345\277\203\345\256\236\347\216\260/redis/impl/RedisFactoryImpl.java" +++ "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21316/\345\210\206\345\270\203\345\274\217\351\224\201/\345\210\206\345\270\203\345\274\217\351\224\201\346\240\270\345\277\203\345\256\236\347\216\260/redis/impl/RedisFactoryImpl.java" @@ -1,12 +1,12 @@ -package 并发编程16.分布式锁核心实现.redis.impl; +package 并发编程16.分布式锁.分布式锁核心实现.redis.impl; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import redis.clients.jedis.Jedis; import redis.clients.jedis.JedisPool; import redis.clients.jedis.JedisPoolConfig; -import 并发编程16.分布式锁核心实现.redis.IRedisFactory; -import 并发编程16.分布式锁核心实现.config.RedisProperties; +import 并发编程16.分布式锁.分布式锁核心实现.redis.IRedisFactory; +import 并发编程16.分布式锁.分布式锁核心实现.config.RedisProperties; /** diff --git "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21316/\345\210\206\345\270\203\345\274\217\351\224\201\346\240\270\345\277\203\345\256\236\347\216\260/redis/impl/RedisServiceImpl.java" "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21316/\345\210\206\345\270\203\345\274\217\351\224\201/\345\210\206\345\270\203\345\274\217\351\224\201\346\240\270\345\277\203\345\256\236\347\216\260/redis/impl/RedisServiceImpl.java" similarity index 94% rename from "src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21316/\345\210\206\345\270\203\345\274\217\351\224\201\346\240\270\345\277\203\345\256\236\347\216\260/redis/impl/RedisServiceImpl.java" rename to "src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21316/\345\210\206\345\270\203\345\274\217\351\224\201/\345\210\206\345\270\203\345\274\217\351\224\201\346\240\270\345\277\203\345\256\236\347\216\260/redis/impl/RedisServiceImpl.java" index 19d231af1c3078b7b5a6b0ec149294e685fb3bee..16a5dd22f26dcd7156036e1b5bb2d67e38624275 100644 --- "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21316/\345\210\206\345\270\203\345\274\217\351\224\201\346\240\270\345\277\203\345\256\236\347\216\260/redis/impl/RedisServiceImpl.java" +++ "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21316/\345\210\206\345\270\203\345\274\217\351\224\201/\345\210\206\345\270\203\345\274\217\351\224\201\346\240\270\345\277\203\345\256\236\347\216\260/redis/impl/RedisServiceImpl.java" @@ -1,12 +1,11 @@ -package 并发编程16.分布式锁核心实现.redis.impl; +package 并发编程16.分布式锁.分布式锁核心实现.redis.impl; -import com.alibaba.fastjson.JSON; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import redis.clients.jedis.*; import redis.clients.jedis.params.SetParams; -import 并发编程16.分布式锁核心实现.redis.IRedisFactory; -import 并发编程16.分布式锁核心实现.redis.IRedisService; +import 并发编程16.分布式锁.分布式锁核心实现.redis.IRedisFactory; +import 并发编程16.分布式锁.分布式锁核心实现.redis.IRedisService; import java.util.*; import java.util.concurrent.TimeUnit; diff --git "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21316/\345\210\206\345\270\203\345\274\217\351\224\201\346\265\213\350\257\225/locktest/DecrApplication.java" "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21316/\345\210\206\345\270\203\345\274\217\351\224\201/\345\210\206\345\270\203\345\274\217\351\224\201\346\265\213\350\257\225/locktest/DecrApplication.java" similarity index 73% rename from "src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21316/\345\210\206\345\270\203\345\274\217\351\224\201\346\265\213\350\257\225/locktest/DecrApplication.java" rename to "src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21316/\345\210\206\345\270\203\345\274\217\351\224\201/\345\210\206\345\270\203\345\274\217\351\224\201\346\265\213\350\257\225/locktest/DecrApplication.java" index be1d0e1d5706c96b449ad6bde72b7e62508dddd1..5a8adba9c632306be33a10c6484a8f8cafbfb875 100644 --- "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21316/\345\210\206\345\270\203\345\274\217\351\224\201\346\265\213\350\257\225/locktest/DecrApplication.java" +++ "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21316/\345\210\206\345\270\203\345\274\217\351\224\201/\345\210\206\345\270\203\345\274\217\351\224\201\346\265\213\350\257\225/locktest/DecrApplication.java" @@ -1,9 +1,9 @@ -package 并发编程16.分布式锁测试.locktest; +package 并发编程16.分布式锁.分布式锁测试.locktest; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.annotation.Import; -import 并发编程16.分布式锁核心实现.config.RedisInitConfiguration; +import 并发编程16.分布式锁.分布式锁核心实现.config.RedisInitConfiguration; /** * @Author idea diff --git "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21316/\345\210\206\345\270\203\345\274\217\351\224\201\346\265\213\350\257\225/locktest/controller/TestController.java" "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21316/\345\210\206\345\270\203\345\274\217\351\224\201/\345\210\206\345\270\203\345\274\217\351\224\201\346\265\213\350\257\225/locktest/controller/TestController.java" similarity index 81% rename from "src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21316/\345\210\206\345\270\203\345\274\217\351\224\201\346\265\213\350\257\225/locktest/controller/TestController.java" rename to "src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21316/\345\210\206\345\270\203\345\274\217\351\224\201/\345\210\206\345\270\203\345\274\217\351\224\201\346\265\213\350\257\225/locktest/controller/TestController.java" index ca9ec9d65cfe9114416333dc673cbaff89c9baa9..d8d7c06143ac7be287f01ef2d51eb955ab05993f 100644 --- "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21316/\345\210\206\345\270\203\345\274\217\351\224\201\346\265\213\350\257\225/locktest/controller/TestController.java" +++ "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21316/\345\210\206\345\270\203\345\274\217\351\224\201/\345\210\206\345\270\203\345\274\217\351\224\201\346\265\213\350\257\225/locktest/controller/TestController.java" @@ -1,9 +1,9 @@ -package 并发编程16.分布式锁测试.locktest.controller; +package 并发编程16.分布式锁.分布式锁测试.locktest.controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; -import 并发编程16.分布式锁测试.locktest.service.TestService; +import 并发编程16.分布式锁.分布式锁测试.locktest.service.TestService; import javax.annotation.Resource; diff --git "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21316/\345\210\206\345\270\203\345\274\217\351\224\201\346\265\213\350\257\225/locktest/service/TestService.java" "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21316/\345\210\206\345\270\203\345\274\217\351\224\201/\345\210\206\345\270\203\345\274\217\351\224\201\346\265\213\350\257\225/locktest/service/TestService.java" similarity index 86% rename from "src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21316/\345\210\206\345\270\203\345\274\217\351\224\201\346\265\213\350\257\225/locktest/service/TestService.java" rename to "src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21316/\345\210\206\345\270\203\345\274\217\351\224\201/\345\210\206\345\270\203\345\274\217\351\224\201\346\265\213\350\257\225/locktest/service/TestService.java" index 0d930ffac705f5b353638146ee6072aaff140be2..b088d95a35d19a33e84d41c4a77939fb6838de6a 100644 --- "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21316/\345\210\206\345\270\203\345\274\217\351\224\201\346\265\213\350\257\225/locktest/service/TestService.java" +++ "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21316/\345\210\206\345\270\203\345\274\217\351\224\201/\345\210\206\345\270\203\345\274\217\351\224\201\346\265\213\350\257\225/locktest/service/TestService.java" @@ -1,8 +1,8 @@ -package 并发编程16.分布式锁测试.locktest.service; +package 并发编程16.分布式锁.分布式锁测试.locktest.service; import org.springframework.stereotype.Service; -import 并发编程16.分布式锁核心实现.lock.IDistributionLock; -import 并发编程16.分布式锁核心实现.redis.IRedisService; +import 并发编程16.分布式锁.分布式锁核心实现.lock.IDistributionLock; +import 并发编程16.分布式锁.分布式锁核心实现.redis.IRedisService; import javax.annotation.Resource; diff --git "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21316/\345\210\206\345\270\203\345\274\217\351\224\201\350\264\237\350\275\275\345\235\207\350\241\241\345\231\250/ClusterApplication.java" "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21316/\345\210\206\345\270\203\345\274\217\351\224\201/\345\210\206\345\270\203\345\274\217\351\224\201\350\264\237\350\275\275\345\235\207\350\241\241\345\231\250/ClusterApplication.java" similarity index 84% rename from "src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21316/\345\210\206\345\270\203\345\274\217\351\224\201\350\264\237\350\275\275\345\235\207\350\241\241\345\231\250/ClusterApplication.java" rename to "src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21316/\345\210\206\345\270\203\345\274\217\351\224\201/\345\210\206\345\270\203\345\274\217\351\224\201\350\264\237\350\275\275\345\235\207\350\241\241\345\231\250/ClusterApplication.java" index a014307806e65f4c57cab60373906c11faec66a3..159c6899c4bfa593f1bb8f44754013ad3fcd4bc2 100644 --- "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21316/\345\210\206\345\270\203\345\274\217\351\224\201\350\264\237\350\275\275\345\235\207\350\241\241\345\231\250/ClusterApplication.java" +++ "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21316/\345\210\206\345\270\203\345\274\217\351\224\201/\345\210\206\345\270\203\345\274\217\351\224\201\350\264\237\350\275\275\345\235\207\350\241\241\345\231\250/ClusterApplication.java" @@ -1,4 +1,4 @@ -package 并发编程16.分布式锁负载均衡器; +package 并发编程16.分布式锁.分布式锁负载均衡器; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; diff --git "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21316/\345\210\206\345\270\203\345\274\217\351\224\201\350\264\237\350\275\275\345\235\207\350\241\241\345\231\250/cluster/ClusterController.java" "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21316/\345\210\206\345\270\203\345\274\217\351\224\201/\345\210\206\345\270\203\345\274\217\351\224\201\350\264\237\350\275\275\345\235\207\350\241\241\345\231\250/cluster/ClusterController.java" similarity index 90% rename from "src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21316/\345\210\206\345\270\203\345\274\217\351\224\201\350\264\237\350\275\275\345\235\207\350\241\241\345\231\250/cluster/ClusterController.java" rename to "src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21316/\345\210\206\345\270\203\345\274\217\351\224\201/\345\210\206\345\270\203\345\274\217\351\224\201\350\264\237\350\275\275\345\235\207\350\241\241\345\231\250/cluster/ClusterController.java" index 9309fa63bc5029a68364825c3f145ffbb425ab8d..ac0b2b5ac71d018e5b2236f080da5da955d896ef 100644 --- "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21316/\345\210\206\345\270\203\345\274\217\351\224\201\350\264\237\350\275\275\345\235\207\350\241\241\345\231\250/cluster/ClusterController.java" +++ "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21316/\345\210\206\345\270\203\345\274\217\351\224\201/\345\210\206\345\270\203\345\274\217\351\224\201\350\264\237\350\275\275\345\235\207\350\241\241\345\231\250/cluster/ClusterController.java" @@ -1,10 +1,10 @@ -package 并发编程16.分布式锁负载均衡器.cluster; +package 并发编程16.分布式锁.分布式锁负载均衡器.cluster; import org.apache.commons.lang3.RandomUtils; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; -import 并发编程16.分布式锁负载均衡器.utils.HttpUtil; +import 并发编程16.分布式锁.分布式锁负载均衡器.utils.HttpUtil; /** * 负载均衡器 diff --git "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21316/\345\210\206\345\270\203\345\274\217\351\224\201\350\264\237\350\275\275\345\235\207\350\241\241\345\231\250/utils/HttpUtil.java" "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21316/\345\210\206\345\270\203\345\274\217\351\224\201/\345\210\206\345\270\203\345\274\217\351\224\201\350\264\237\350\275\275\345\235\207\350\241\241\345\231\250/utils/HttpUtil.java" similarity index 95% rename from "src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21316/\345\210\206\345\270\203\345\274\217\351\224\201\350\264\237\350\275\275\345\235\207\350\241\241\345\231\250/utils/HttpUtil.java" rename to "src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21316/\345\210\206\345\270\203\345\274\217\351\224\201/\345\210\206\345\270\203\345\274\217\351\224\201\350\264\237\350\275\275\345\235\207\350\241\241\345\231\250/utils/HttpUtil.java" index b611ec88904ef8aae5c2de3eb563b1205d7a4f87..b28229cc29ba41d42eeda7d06b9f474bd59da662 100644 --- "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21316/\345\210\206\345\270\203\345\274\217\351\224\201\350\264\237\350\275\275\345\235\207\350\241\241\345\231\250/utils/HttpUtil.java" +++ "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21316/\345\210\206\345\270\203\345\274\217\351\224\201/\345\210\206\345\270\203\345\274\217\351\224\201\350\264\237\350\275\275\345\235\207\350\241\241\345\231\250/utils/HttpUtil.java" @@ -1,4 +1,4 @@ -package 并发编程16.分布式锁负载均衡器.utils; +package 并发编程16.分布式锁.分布式锁负载均衡器.utils; import java.io.BufferedReader; diff --git "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21319/\346\227\245\345\277\227\347\273\204\344\273\266\345\272\225\345\261\202/LogApplication.java" "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21319/\346\227\245\345\277\227\347\273\204\344\273\266/\346\227\245\345\277\227\347\273\204\344\273\266\345\272\225\345\261\202/LogApplication.java" similarity index 89% rename from "src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21319/\346\227\245\345\277\227\347\273\204\344\273\266\345\272\225\345\261\202/LogApplication.java" rename to "src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21319/\346\227\245\345\277\227\347\273\204\344\273\266/\346\227\245\345\277\227\347\273\204\344\273\266\345\272\225\345\261\202/LogApplication.java" index bbea9a86d5917371baa29d6405a9b3c67627f43a..5aea55583a09d363af1f044fc91ad5755e6a1083 100644 --- "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21319/\346\227\245\345\277\227\347\273\204\344\273\266\345\272\225\345\261\202/LogApplication.java" +++ "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21319/\346\227\245\345\277\227\347\273\204\344\273\266/\346\227\245\345\277\227\347\273\204\344\273\266\345\272\225\345\261\202/LogApplication.java" @@ -1,4 +1,4 @@ -package 并发编程19.日志组件底层; +package 并发编程19.日志组件.日志组件底层; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; diff --git "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21319/\346\227\245\345\277\227\347\273\204\344\273\266\345\272\225\345\261\202/controller/TestController.java" "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21319/\346\227\245\345\277\227\347\273\204\344\273\266/\346\227\245\345\277\227\347\273\204\344\273\266\345\272\225\345\261\202/controller/TestController.java" similarity index 89% rename from "src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21319/\346\227\245\345\277\227\347\273\204\344\273\266\345\272\225\345\261\202/controller/TestController.java" rename to "src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21319/\346\227\245\345\277\227\347\273\204\344\273\266/\346\227\245\345\277\227\347\273\204\344\273\266\345\272\225\345\261\202/controller/TestController.java" index bef2d0b4c9916b8a8929c236e9dadd432e853bac..e601f78e7b21bb4c1c0cbb233e4ae36285b4ac2e 100644 --- "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21319/\346\227\245\345\277\227\347\273\204\344\273\266\345\272\225\345\261\202/controller/TestController.java" +++ "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21319/\346\227\245\345\277\227\347\273\204\344\273\266/\346\227\245\345\277\227\347\273\204\344\273\266\345\272\225\345\261\202/controller/TestController.java" @@ -1,4 +1,4 @@ -package 并发编程19.日志组件底层.controller; +package 并发编程19.日志组件.日志组件底层.controller; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21319/\346\227\245\345\277\227\347\273\204\344\273\266\346\241\210\344\276\213/Logger.java" "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21319/\346\227\245\345\277\227\347\273\204\344\273\266/\346\227\245\345\277\227\347\273\204\344\273\266\346\241\210\344\276\213/Logger.java" similarity index 91% rename from "src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21319/\346\227\245\345\277\227\347\273\204\344\273\266\346\241\210\344\276\213/Logger.java" rename to "src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21319/\346\227\245\345\277\227\347\273\204\344\273\266/\346\227\245\345\277\227\347\273\204\344\273\266\346\241\210\344\276\213/Logger.java" index f4b150bb67991272d7ea37245312e00cf475bc21..b5ccaffb0928cf5982e04b184a49a37107270fe5 100644 --- "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21319/\346\227\245\345\277\227\347\273\204\344\273\266\346\241\210\344\276\213/Logger.java" +++ "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21319/\346\227\245\345\277\227\347\273\204\344\273\266/\346\227\245\345\277\227\347\273\204\344\273\266\346\241\210\344\276\213/Logger.java" @@ -1,4 +1,4 @@ -package 并发编程19.日志组件案例; +package 并发编程19.日志组件.日志组件案例; import org.slf4j.LoggerFactory; diff --git "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21319/\346\227\245\345\277\227\347\273\204\344\273\266\346\241\210\344\276\213/PayLogDemo.java" "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21319/\346\227\245\345\277\227\347\273\204\344\273\266/\346\227\245\345\277\227\347\273\204\344\273\266\346\241\210\344\276\213/PayLogDemo.java" similarity index 93% rename from "src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21319/\346\227\245\345\277\227\347\273\204\344\273\266\346\241\210\344\276\213/PayLogDemo.java" rename to "src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21319/\346\227\245\345\277\227\347\273\204\344\273\266/\346\227\245\345\277\227\347\273\204\344\273\266\346\241\210\344\276\213/PayLogDemo.java" index 2757211e589c3d8aff221634db1753cdee737c40..47286bda39f0cea29e57f990c20f61f4caf4b1c6 100644 --- "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21319/\346\227\245\345\277\227\347\273\204\344\273\266\346\241\210\344\276\213/PayLogDemo.java" +++ "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21319/\346\227\245\345\277\227\347\273\204\344\273\266/\346\227\245\345\277\227\347\273\204\344\273\266\346\241\210\344\276\213/PayLogDemo.java" @@ -1,4 +1,4 @@ -package 并发编程19.日志组件案例; +package 并发编程19.日志组件.日志组件案例; /** * 一个简单的日志记录案例 diff --git "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21319/\346\227\245\345\277\227\347\273\204\344\273\266\346\241\210\344\276\213/PayNotifyVO.java" "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21319/\346\227\245\345\277\227\347\273\204\344\273\266/\346\227\245\345\277\227\347\273\204\344\273\266\346\241\210\344\276\213/PayNotifyVO.java" similarity index 81% rename from "src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21319/\346\227\245\345\277\227\347\273\204\344\273\266\346\241\210\344\276\213/PayNotifyVO.java" rename to "src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21319/\346\227\245\345\277\227\347\273\204\344\273\266/\346\227\245\345\277\227\347\273\204\344\273\266\346\241\210\344\276\213/PayNotifyVO.java" index 1789086b390ab754d8c4951862b19d2956dbef55..550520eb955da30a2224bf52de9263b08580053a 100644 --- "a/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21319/\346\227\245\345\277\227\347\273\204\344\273\266\346\241\210\344\276\213/PayNotifyVO.java" +++ "b/src/main/java/\345\271\266\345\217\221\347\274\226\347\250\21319/\346\227\245\345\277\227\347\273\204\344\273\266/\346\227\245\345\277\227\347\273\204\344\273\266\346\241\210\344\276\213/PayNotifyVO.java" @@ -1,4 +1,4 @@ -package 并发编程19.日志组件案例; +package 并发编程19.日志组件.日志组件案例; /** * @Author linhao