diff --git a/.DS_Store b/.DS_Store
new file mode 100644
index 0000000..454757c
Binary files /dev/null and b/.DS_Store differ
diff --git a/README.md b/README.md
index 4d66a32..79d2603 100755
--- a/README.md
+++ b/README.md
@@ -1,66 +1,22 @@
## 1 目标
-致力于建立全球最完善的 Java 高并发理论体系。让我们的程序更加可靠,跳槽面试更轻松。
+致力于构建全球最完善的 Java 高并发理论体系。让我们的程序更加可靠,跳槽面试更轻松。
-## 2 深入底层原理,实现并发业务
-- 线程N种实现方式
-
-- 线程启动你真的会么?
-
-- 线程停止、中断的最佳实践
-
-- 线程生命周期
-
-- 趣解Thread和Object类中线程相关方法:wait、notify、join、yield…
-
-- 线程属性
-
-- 线程异常处理
-
-- 线程安全与程序性能的取舍之道
-
-...
-
-## 3 环境参数
-
-- Maven 3.6+
-
-- JDK 8+
-
-- Tomcat 8.5+
-
-- MySQL 8.0.16+
-
-- Redis 6.0+
-
-- Intellij IDEA 2019.3
-
-## 4 方案概要
+## 高并发方案概要
### 线程安全性
-线程安全性,主要从原子性、可见性、有序性三个方面
-
-原子性部分, atomic包下相关类、CAS原理、Unsafe类、synchronized关键字等的使用及注意事项
-
-可见性部分,主要介绍的是volatile关键字的规则和使用,及synchronized关键字的可见性
-
-有序性部分,则重点讲解了happens-before原则
+线程安全性,主要从原子性、可见性、有序性
### 安全发布对象
-安全发布对象的一些核心方法,主要通过单例类的多种实现方式,让大家在实现过程中去体会这些方法的具体含义
-这也是对线程安全性的巩固,也是把线程安全性涉及的一些关键字和类再一次放到实际场景中使用,加深大家对他们的印象和认识
+安全发布对象的一些核心方法,主要通过单例类的多种实现方式体会,这也是对线程安全性的巩固,也是把线程安全性涉及的一些关键字和类再一次放到实际场景使用。
### 线程安全策略
线程安全策略,包括定义不可变对象、线程封闭、同步容器、并发容器等,引出并发里的关键知识J.U.C。
-
-同时还额外介绍了开发中常见的一些线程不安全类和写法,并给出他们各自对应的替代方案。这一章涉及的内容在日常开发和面试中都会涉及很多。...
+同时还额外介绍了开发中常见的一些线程不安全类和写法,并给出他们各自对应的替代方案。
### AQS
+J.U.C的重要组件,面试必问考点。
-J.U.C的重要组件,也是面试的重要考点。
-
-AQS模型设计及相关同步组件的原理和使用,都非常实用
-
-具体包括:CountDownLatch、Semaphore、CyclicBarrier、ReentrantLock与锁、Condition等。
+AQS模型设计及相关同步组件的原理和使用,都非常实用,包括:CountDownLatch、Semaphore、CyclicBarrier、ReentrantLock与锁、Condition等。
这些组件需要大家能熟练明白他们的用途及差异,不但会使用,而且还要明确知道不同方法调用后的不同效果。
@@ -71,38 +27,52 @@ J.U.C相关组件,主要包括FutureTask、Fork/Join框架、BlockingQueue,
这些组件使用场景相对AQS会少一些,但也是J.U.C的重要组成部分,也是需要掌握的
### 线程调度-线程池
-J.U.C里最后一部分:线程池。面试大概率会问到线程池相关的知识点。
+new Thread弊端、线程池的好处、ThreadPoolExecutor详细介绍(参数、状态、方法)、线程池类图、Executor框架接口
-这一章将主要从new Thread弊端、线程池的好处、ThreadPoolExecutor详细介绍(参数、状态、方法)、线程池类图、Executor框架接口等进行讲解,需要大家能了解线程池的许多细节及配置,并能在实际项目中正确使用
-
-### 多线程并发拓展讲解
-对并发编程做些补充,但都贴近当前的面试,主要讲解死锁产生的条件及预防、多线程并发编程的最佳实践、Spring与线程安全、以及面试都特别喜欢问的HashMap和ConcurrentMap源码细节。当然,面试喜欢问的问题,对实际项目开发也是特别重要的
+### 多线程并发拓展
+死锁产生的条件及预防、多线程并发编程的最佳实践、Spring与线程安全、以及面试都特别喜欢问的HashMap和ConcurrentMap源码细节
### 扩容
-高并发部分:思路,侧重面试,扩容思路,首先介绍垂直扩容和水平扩容的区别,数据库读操作扩展和写操作扩展思路。
+垂直扩容和水平扩容的区别,数据库读操作扩展和写操作扩展
### 缓存
-思路,本章讲解高并发中缓存方案。
-
-包含对缓存特征(命中率、最大元素、清空策略)、影响缓存命中率因素、缓存分类和应用场景(本地缓存、分布式缓存)、高并发场景下缓存常见问题(缓存一致性、缓存并发、缓存穿透、雪崩)等的具体介绍。此外,针对大家常用的缓存组件Guava Cache、Memcache、Redis
+缓存特征(命中率、最大元素、清空策略)、影响缓存命中率因素、缓存分类和应用场景(本地缓存、分布式缓存)、高并发场景下缓存常见问题(缓存一致性、缓存并发、缓存穿透、雪崩)
-### 消息队列
-消息队列的特性(业务无关、FIFO、容灾、性能)、为什么需要消息队列以及消息队列的好处(业务解耦、最终一致性、广播、错峰与流控),对当前比较流行的消息队列组件kafka和rabbitmq做架构分析和特性介绍
+### MQ
+消息队列的特性(业务无关、FIFO、容灾、性能)、为什么需要消息队列以及消息队列的好处(业务解耦、最终一致性、广播、错峰与流控)
-### 应用拆分
-从实际项目拆分步骤讲起,让大家可以实际感受到应用拆分的好处和解决的问题,之后引出对应用拆分原则(业务优先、循序渐进、兼顾技术、可靠测试)和应用拆分时思考的内容(应用之间通信、应用之间数据库设计、避免事务跨应用),并引出对服务化Dubbo和微服务Spring Cloud的框架介绍
+### 应用拆分
### 限流
明确限流的重要作用
-限流常用的四种算法:计数法、滑动窗口、漏桶算法和令牌桶算法,并对他们做了简单的对比
+限流常用的四种算法:计数法、滑动窗口、漏桶算法和令牌桶算法
### 服务降级与服务熔断
服务降级的分类:自动降级(超时、失败次数、故障、限流)和人工降级(开关),总结了服务降级和服务熔断的共性(目的、最终表现、粒度、自治)和区别(出发原因、管理目标层次、实现方式)以及服务降级要考虑的问题
-### 数据库分库分表与高可用
-高并发部分:主讲思路,从数据库瓶颈开始讲起,引出对数据库切库分库分表的介绍。数据库切库里重点介绍了读写分离的设计,对比支持多数据源和分库的区别;
+### 分库分表
+
+## QQ 技术交流群
+
+为大家提供一个学习交流平台,在这里你可以自由地讨论技术问题。
+
+
+
+## 微信交流群
+
+
+### 本人微信
+
+
+## Java源码模拟面试解析指南
+
+
+
+
-什么时候该考虑分表、横向分表与纵向分表,以及通过mybatis的分页插件shardbatis2.0实现数据库分表
+### 绘图工具
+- [draw.io](https://www.draw.io/)
+- keynote
## 知识体系

diff --git a/assets/LOGO.png b/assets/LOGO.png
new file mode 100644
index 0000000..b5e3b09
Binary files /dev/null and b/assets/LOGO.png differ
diff --git "a/assets/QQ \347\276\244.JPG" "b/assets/QQ \347\276\244.JPG"
new file mode 100644
index 0000000..c6a3f39
Binary files /dev/null and "b/assets/QQ \347\276\244.JPG" differ
diff --git "a/assets/\344\270\252\344\272\272\345\276\256\344\277\241.jpeg" "b/assets/\344\270\252\344\272\272\345\276\256\344\277\241.jpeg"
new file mode 100644
index 0000000..35b73f0
Binary files /dev/null and "b/assets/\344\270\252\344\272\272\345\276\256\344\277\241.jpeg" differ
diff --git "a/assets/\345\205\254\344\274\227\345\217\267.png" "b/assets/\345\205\254\344\274\227\345\217\267.png"
new file mode 100644
index 0000000..e8c9c92
Binary files /dev/null and "b/assets/\345\205\254\344\274\227\345\217\267.png" differ
diff --git "a/assets/\345\276\256\344\277\241\347\276\244.jpeg" "b/assets/\345\276\256\344\277\241\347\276\244.jpeg"
new file mode 100644
index 0000000..abeb9ae
Binary files /dev/null and "b/assets/\345\276\256\344\277\241\347\276\244.jpeg" differ
diff --git "a/assets/\347\211\233\345\256\242\344\270\223\345\210\212.png" "b/assets/\347\211\233\345\256\242\344\270\223\345\210\212.png"
new file mode 100644
index 0000000..6f48493
Binary files /dev/null and "b/assets/\347\211\233\345\256\242\344\270\223\345\210\212.png" differ
diff --git a/mvnw b/mvnw
index 5bf251c..df68171 100755
--- a/mvnw
+++ b/mvnw
@@ -55,7 +55,7 @@ case "`uname`" in
MINGW*) mingw=true;;
Darwin*) darwin=true
# Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home
- # See https://developer.apple.com/library/mac/qa/qa1170/_index.html
+ # See https://developer.JavaEdge.com/library/mac/qa/qa1170/_index.html
if [ -z "$JAVA_HOME" ]; then
if [ -x "/usr/libexec/java_home" ]; then
export JAVA_HOME="`/usr/libexec/java_home`"
diff --git a/pom.xml b/pom.xml
index 9eade25..19c29f6 100755
--- a/pom.xml
+++ b/pom.xml
@@ -6,7 +6,6 @@
com.javaedge
concurrency
0.0.1-SNAPSHOT
- war
concurrency
Demo project for Spring Boot
@@ -90,6 +89,20 @@
compile
+
+ org.projectlombok
+ lombok
+
+
+ junit
+ junit
+
+
+
+ io.netty
+ netty-all
+ 4.1.15.Final
+
diff --git a/src/main/java/AppendixA/Main.java b/src/main/java/AppendixA/Main.java
new file mode 100644
index 0000000..ebfb1b9
--- /dev/null
+++ b/src/main/java/AppendixA/Main.java
@@ -0,0 +1,9 @@
+package main.java.AppendixA;
+
+public class Main {
+ public static void main(String[] args) {
+ System.out.println(Thread.currentThread().getName() + ":BEGIN");
+ new MyFrame();
+ System.out.println(Thread.currentThread().getName() + ":END");
+ }
+}
diff --git a/src/main/java/AppendixA/MyFrame.java b/src/main/java/AppendixA/MyFrame.java
new file mode 100644
index 0000000..7e8fa87
--- /dev/null
+++ b/src/main/java/AppendixA/MyFrame.java
@@ -0,0 +1,63 @@
+package main.java.AppendixA;
+
+import javax.swing.JFrame;
+import javax.swing.JButton;
+import javax.swing.JLabel;
+import javax.swing.SwingUtilities;
+import java.awt.FlowLayout;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+
+
+public class MyFrame extends JFrame implements ActionListener {
+ private final JLabel label = new JLabel("Event Dispatching Thread Sample");
+ private final JButton button = new JButton("countUp");
+ public MyFrame() {
+ super("MyFrame");
+ getContentPane().setLayout(new FlowLayout());
+ getContentPane().add(label);
+ getContentPane().add(button);
+ button.addActionListener(this);
+ setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+ pack();
+ setVisible(true);
+ }
+ public void actionPerformed(ActionEvent e) {
+ if (e.getSource() == button) {
+ countUp();
+ }
+ }
+ private void countUp() {
+ System.out.println(Thread.currentThread().getName() + ":countUp:BEGIN");
+
+ // invokerThread��ָ��ʱ����sleep֮����SwingUtilities.invokeLater
+ new Thread("invokerThread") {
+ public void run() {
+ System.out.println(Thread.currentThread().getName() + ":invokerThread:BEGIN");
+ for (int i = 0; i < 10; i++) {
+ final String string = "" + i;
+ try {
+ // executor�ᱻ��Event Dispatching Thread����
+ final Runnable executor = new Runnable() {
+ public void run() {
+ System.out.println(Thread.currentThread().getName() + ":executor:BEGIN:string = " + string);
+ label.setText(string);
+ System.out.println(Thread.currentThread().getName() + ":executor:END");
+ }
+ };
+
+ // ��Event Dispatching Thread���ó�exector
+ SwingUtilities.invokeLater(executor);
+
+ Thread.sleep(1000);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+ System.out.println(Thread.currentThread().getName() + ":invokerThread:END");
+ }
+ }.start();
+
+ System.out.println(Thread.currentThread().getName() + ":countUp:END");
+ }
+}
diff --git a/src/main/java/Balking/Q5/TestThread.java b/src/main/java/Balking/Q5/TestThread.java
new file mode 100644
index 0000000..2c4466f
--- /dev/null
+++ b/src/main/java/Balking/Q5/TestThread.java
@@ -0,0 +1,15 @@
+package main.java.Balking.Q5;
+
+public class TestThread extends Thread {
+ public void run() {
+ System.out.print("BEGIN");
+ for (int i = 0; i < 50; i++) {
+ System.out.print(".");
+ try {
+ Thread.sleep(100);
+ } catch (InterruptedException e) {
+ }
+ }
+ System.out.println("END");
+ }
+}
diff --git a/src/main/java/Balking/Sample/ChangerThread.java b/src/main/java/Balking/Sample/ChangerThread.java
new file mode 100644
index 0000000..e058762
--- /dev/null
+++ b/src/main/java/Balking/Sample/ChangerThread.java
@@ -0,0 +1,26 @@
+//package Balking.Sample;
+//
+//import java.io.IOException;
+//import java.util.Random;
+//
+//public class ChangerThread extends Thread {
+// private Data data;
+// private Random random = new Random();
+// public ChangerThread(String name, Data data) {
+// super(name);
+// this.data = data;
+// }
+// public void run() {
+// try {
+// for (int i = 0; true; i++) {
+// data.change("No." + i); //�����Ϯ�
+// Thread.sleep(random.nextInt(1000)); // ģ��ȥ���������
+// data.save(); // ��ȷ��Ҫ��浵
+// }
+// } catch (IOException e) {
+// e.printStackTrace();
+// } catch (InterruptedException e) {
+// e.printStackTrace();
+// }
+// }
+//}
diff --git a/src/main/java/Immutable/A6_2/Main.java b/src/main/java/Immutable/A6_2/Main.java
new file mode 100644
index 0000000..1f8fec5
--- /dev/null
+++ b/src/main/java/Immutable/A6_2/Main.java
@@ -0,0 +1,31 @@
+//package Immutable.A6_2;
+//
+//import person.MutablePerson;
+//import person.ImmutablePerson;
+//
+//public class Main {
+// public static void main(String[] args) {
+// MutablePerson mutable = new MutablePerson("start", "start");
+// new CrackerThread(mutable).start();
+// new CrackerThread(mutable).start();
+// new CrackerThread(mutable).start();
+// for (int i = 0; true; i++) {
+// mutable.setPerson("" + i, "" + i);
+// }
+// }
+//}
+//
+//class CrackerThread extends Thread {
+// private final MutablePerson mutable;
+// public CrackerThread(MutablePerson mutable) {
+// this.mutable = mutable;
+// }
+// public void run() {
+// while (true) {
+// ImmutablePerson immutable = new ImmutablePerson(mutable);
+// if (!immutable.getName().equals(immutable.getAddress())) {
+// System.out.println(currentThread().getName() + " ***** BROKEN ***** " + immutable);
+// }
+// }
+// }
+//}
diff --git a/src/main/java/Immutable/Q2/Main.java b/src/main/java/Immutable/Q2/Main.java
new file mode 100644
index 0000000..8216518
--- /dev/null
+++ b/src/main/java/Immutable/Q2/Main.java
@@ -0,0 +1,8 @@
+package main.java.Immutable.Q2;
+
+public class Main {
+ public static void main(String[] args) {
+ String s = "BAT";
+ System.out.println(s.replace('B', 'C')); // 'B'ȡ����'C'
+ }
+}
diff --git a/concurrency/src/main/java/com/javaedge/concurrency/ConcurrencyApplication.java b/src/main/java/com/javaedge/concurrency/ConcurrencyApplication.java
similarity index 95%
rename from concurrency/src/main/java/com/javaedge/concurrency/ConcurrencyApplication.java
rename to src/main/java/com/javaedge/concurrency/ConcurrencyApplication.java
index edd52be..aec342b 100755
--- a/concurrency/src/main/java/com/javaedge/concurrency/ConcurrencyApplication.java
+++ b/src/main/java/com/javaedge/concurrency/ConcurrencyApplication.java
@@ -1,4 +1,4 @@
-package com.javaedge.concurrency;
+package main.java.com.javaedge.concurrency;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
diff --git a/concurrency/src/main/java/com/javaedge/concurrency/ConcurrencyTest.java b/src/main/java/com/javaedge/concurrency/ConcurrencyTest.java
similarity index 96%
rename from concurrency/src/main/java/com/javaedge/concurrency/ConcurrencyTest.java
rename to src/main/java/com/javaedge/concurrency/ConcurrencyTest.java
index 2967863..12867a7 100755
--- a/concurrency/src/main/java/com/javaedge/concurrency/ConcurrencyTest.java
+++ b/src/main/java/com/javaedge/concurrency/ConcurrencyTest.java
@@ -1,4 +1,4 @@
-package com.javaedge.concurrency;
+package main.java.com.javaedge.concurrency;
import com.javaedge.concurrency.annoations.NotThreadSafe;
import lombok.extern.slf4j.Slf4j;
diff --git a/concurrency/src/main/java/com/javaedge/concurrency/HttpFilter.java b/src/main/java/com/javaedge/concurrency/HttpFilter.java
similarity index 90%
rename from concurrency/src/main/java/com/javaedge/concurrency/HttpFilter.java
rename to src/main/java/com/javaedge/concurrency/HttpFilter.java
index aec3df4..87dcb65 100755
--- a/concurrency/src/main/java/com/javaedge/concurrency/HttpFilter.java
+++ b/src/main/java/com/javaedge/concurrency/HttpFilter.java
@@ -1,6 +1,6 @@
-package com.javaedge.concurrency;
+package main.java.com.javaedge.concurrency;
-import com.javaedge.concurrency.example.threadLocal.RequestHolder;
+import com.javaedge.concurrency.threadLocal.RequestHolder;
import lombok.extern.slf4j.Slf4j;
import javax.servlet.Filter;
diff --git a/concurrency/src/main/java/com/javaedge/concurrency/HttpInterceptor.java b/src/main/java/com/javaedge/concurrency/HttpInterceptor.java
similarity index 87%
rename from concurrency/src/main/java/com/javaedge/concurrency/HttpInterceptor.java
rename to src/main/java/com/javaedge/concurrency/HttpInterceptor.java
index 4ed6d77..5172654 100755
--- a/concurrency/src/main/java/com/javaedge/concurrency/HttpInterceptor.java
+++ b/src/main/java/com/javaedge/concurrency/HttpInterceptor.java
@@ -1,6 +1,6 @@
-package com.javaedge.concurrency;
+package main.java.com.javaedge.concurrency;
-import com.javaedge.concurrency.example.threadLocal.RequestHolder;
+import com.javaedge.concurrency.threadLocal.RequestHolder;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
diff --git a/concurrency/src/main/java/com/javaedge/concurrency/example/LockSupportBlockerTest.java b/src/main/java/com/javaedge/concurrency/LockSupportBlockerTest.java
similarity index 88%
rename from concurrency/src/main/java/com/javaedge/concurrency/example/LockSupportBlockerTest.java
rename to src/main/java/com/javaedge/concurrency/LockSupportBlockerTest.java
index a4c018c..7b9ae45 100644
--- a/concurrency/src/main/java/com/javaedge/concurrency/example/LockSupportBlockerTest.java
+++ b/src/main/java/com/javaedge/concurrency/LockSupportBlockerTest.java
@@ -1,3 +1,8 @@
+package main.java.com.javaedge.concurrency;
+
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.locks.LockSupport;
+
public class LockSupportBlockerTest {
public static void main(String[] args) {
Thread t3 = new Thread(() -> {
diff --git a/concurrency/src/main/java/com/javaedge/concurrency/example/LockSupportTest.java b/src/main/java/com/javaedge/concurrency/LockSupportTest.java
similarity index 97%
rename from concurrency/src/main/java/com/javaedge/concurrency/example/LockSupportTest.java
rename to src/main/java/com/javaedge/concurrency/LockSupportTest.java
index 624b1cb..6b3f543 100644
--- a/concurrency/src/main/java/com/javaedge/concurrency/example/LockSupportTest.java
+++ b/src/main/java/com/javaedge/concurrency/LockSupportTest.java
@@ -1,4 +1,4 @@
-package com.javaedge.concurrency.example;
+package main.java.com.javaedge.concurrency;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.LockSupport;
diff --git a/concurrency/src/main/java/com/javaedge/concurrency/TestController.java b/src/main/java/com/javaedge/concurrency/TestController.java
similarity index 89%
rename from concurrency/src/main/java/com/javaedge/concurrency/TestController.java
rename to src/main/java/com/javaedge/concurrency/TestController.java
index bc49c01..1429afc 100755
--- a/concurrency/src/main/java/com/javaedge/concurrency/TestController.java
+++ b/src/main/java/com/javaedge/concurrency/TestController.java
@@ -1,4 +1,4 @@
-package com.javaedge.concurrency;
+package main.java.com.javaedge.concurrency;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Controller;
diff --git a/concurrency/src/main/java/com/javaedge/concurrency/example/UnsafeTest.java b/src/main/java/com/javaedge/concurrency/UnsafeTest.java
similarity index 72%
rename from concurrency/src/main/java/com/javaedge/concurrency/example/UnsafeTest.java
rename to src/main/java/com/javaedge/concurrency/UnsafeTest.java
index 138606c..6459a0a 100644
--- a/concurrency/src/main/java/com/javaedge/concurrency/example/UnsafeTest.java
+++ b/src/main/java/com/javaedge/concurrency/UnsafeTest.java
@@ -1,19 +1,26 @@
+package main.java.com.javaedge.concurrency;
+
+import sun.misc.Unsafe;
+
+import java.lang.reflect.Field;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * @author JavaEdge
+ */
public class UnsafeTest {
public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException {
Field f = Unsafe.class.getDeclaredField("theUnsafe");
f.setAccessible(true);
Unsafe unsafe = (Unsafe) f.get(null);
- Thread t1 = new Thread() {
- @Override
- public void run() {
- Thread.currentThread().setName("t1");
- System.out.println(Thread.currentThread().getName() + " before park");
- //park 100 seconds
- unsafe.park(false, TimeUnit.NANOSECONDS.convert(100, TimeUnit.SECONDS));
- System.out.println(Thread.currentThread().getName() + " after park");
- }
- };
+ Thread t1 = new Thread(() -> {
+ Thread.currentThread().setName("t1");
+ System.out.println(Thread.currentThread().getName() + " before park");
+ //park 100 seconds
+ unsafe.park(false, TimeUnit.NANOSECONDS.convert(100, TimeUnit.SECONDS));
+ System.out.println(Thread.currentThread().getName() + " after park");
+ });
Thread t2 = new Thread() {
@Override
public void run() {
diff --git a/concurrency/src/main/java/com/javaedge/concurrency/annoations/NotRecommend.java b/src/main/java/com/javaedge/concurrency/annoations/NotRecommend.java
similarity index 86%
rename from concurrency/src/main/java/com/javaedge/concurrency/annoations/NotRecommend.java
rename to src/main/java/com/javaedge/concurrency/annoations/NotRecommend.java
index b1f1268..51563d1 100755
--- a/concurrency/src/main/java/com/javaedge/concurrency/annoations/NotRecommend.java
+++ b/src/main/java/com/javaedge/concurrency/annoations/NotRecommend.java
@@ -1,4 +1,4 @@
-package com.javaedge.concurrency.annoations;
+package main.java.com.javaedge.concurrency.annoations;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
diff --git a/concurrency/src/main/java/com/javaedge/concurrency/annoations/NotThreadSafe.java b/src/main/java/com/javaedge/concurrency/annoations/NotThreadSafe.java
similarity index 86%
rename from concurrency/src/main/java/com/javaedge/concurrency/annoations/NotThreadSafe.java
rename to src/main/java/com/javaedge/concurrency/annoations/NotThreadSafe.java
index 3413bd8..479d656 100755
--- a/concurrency/src/main/java/com/javaedge/concurrency/annoations/NotThreadSafe.java
+++ b/src/main/java/com/javaedge/concurrency/annoations/NotThreadSafe.java
@@ -1,4 +1,4 @@
-package com.javaedge.concurrency.annoations;
+package main.java.com.javaedge.concurrency.annoations;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
diff --git a/concurrency/src/main/java/com/javaedge/concurrency/annoations/Recommend.java b/src/main/java/com/javaedge/concurrency/annoations/Recommend.java
similarity index 86%
rename from concurrency/src/main/java/com/javaedge/concurrency/annoations/Recommend.java
rename to src/main/java/com/javaedge/concurrency/annoations/Recommend.java
index 6e8c350..ca616cc 100755
--- a/concurrency/src/main/java/com/javaedge/concurrency/annoations/Recommend.java
+++ b/src/main/java/com/javaedge/concurrency/annoations/Recommend.java
@@ -1,4 +1,4 @@
-package com.javaedge.concurrency.annoations;
+package main.java.com.javaedge.concurrency.annoations;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
diff --git a/concurrency/src/main/java/com/javaedge/concurrency/annoations/ThreadSafe.java b/src/main/java/com/javaedge/concurrency/annoations/ThreadSafe.java
similarity index 86%
rename from concurrency/src/main/java/com/javaedge/concurrency/annoations/ThreadSafe.java
rename to src/main/java/com/javaedge/concurrency/annoations/ThreadSafe.java
index c38ef6f..e248e53 100755
--- a/concurrency/src/main/java/com/javaedge/concurrency/annoations/ThreadSafe.java
+++ b/src/main/java/com/javaedge/concurrency/annoations/ThreadSafe.java
@@ -1,4 +1,4 @@
-package com.javaedge.concurrency.annoations;
+package main.java.com.javaedge.concurrency.annoations;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
diff --git a/concurrency/src/main/java/com/javaedge/concurrency/example/aqs/CountDownLatchExample1.java b/src/main/java/com/javaedge/concurrency/aqs/CountDownLatchExample1.java
similarity index 95%
rename from concurrency/src/main/java/com/javaedge/concurrency/example/aqs/CountDownLatchExample1.java
rename to src/main/java/com/javaedge/concurrency/aqs/CountDownLatchExample1.java
index ce28dda..7cbc186 100755
--- a/concurrency/src/main/java/com/javaedge/concurrency/example/aqs/CountDownLatchExample1.java
+++ b/src/main/java/com/javaedge/concurrency/aqs/CountDownLatchExample1.java
@@ -1,4 +1,4 @@
-package com.javaedge.concurrency.example.aqs;
+package main.java.com.javaedge.concurrency.aqs;
import lombok.extern.slf4j.Slf4j;
diff --git a/concurrency/src/main/java/com/javaedge/concurrency/example/aqs/CountDownLatchExample2.java b/src/main/java/com/javaedge/concurrency/aqs/CountDownLatchExample2.java
similarity index 95%
rename from concurrency/src/main/java/com/javaedge/concurrency/example/aqs/CountDownLatchExample2.java
rename to src/main/java/com/javaedge/concurrency/aqs/CountDownLatchExample2.java
index 65dacf0..2ae325e 100755
--- a/concurrency/src/main/java/com/javaedge/concurrency/example/aqs/CountDownLatchExample2.java
+++ b/src/main/java/com/javaedge/concurrency/aqs/CountDownLatchExample2.java
@@ -1,4 +1,4 @@
-package com.javaedge.concurrency.example.aqs;
+package main.java.com.javaedge.concurrency.aqs;
import lombok.extern.slf4j.Slf4j;
diff --git a/concurrency/src/main/java/com/javaedge/concurrency/example/aqs/CyclicBarrierExample1.java b/src/main/java/com/javaedge/concurrency/aqs/CyclicBarrierExample1.java
similarity index 95%
rename from concurrency/src/main/java/com/javaedge/concurrency/example/aqs/CyclicBarrierExample1.java
rename to src/main/java/com/javaedge/concurrency/aqs/CyclicBarrierExample1.java
index f117926..694afd5 100755
--- a/concurrency/src/main/java/com/javaedge/concurrency/example/aqs/CyclicBarrierExample1.java
+++ b/src/main/java/com/javaedge/concurrency/aqs/CyclicBarrierExample1.java
@@ -1,4 +1,4 @@
-package com.javaedge.concurrency.example.aqs;
+package main.java.com.javaedge.concurrency.aqs;
import lombok.extern.slf4j.Slf4j;
diff --git a/concurrency/src/main/java/com/javaedge/concurrency/example/aqs/CyclicBarrierExample2.java b/src/main/java/com/javaedge/concurrency/aqs/CyclicBarrierExample2.java
similarity index 96%
rename from concurrency/src/main/java/com/javaedge/concurrency/example/aqs/CyclicBarrierExample2.java
rename to src/main/java/com/javaedge/concurrency/aqs/CyclicBarrierExample2.java
index 19024d8..3894267 100755
--- a/concurrency/src/main/java/com/javaedge/concurrency/example/aqs/CyclicBarrierExample2.java
+++ b/src/main/java/com/javaedge/concurrency/aqs/CyclicBarrierExample2.java
@@ -1,4 +1,4 @@
-package com.javaedge.concurrency.example.aqs;
+package main.java.com.javaedge.concurrency.aqs;
import lombok.extern.slf4j.Slf4j;
diff --git a/concurrency/src/main/java/com/javaedge/concurrency/example/aqs/CyclicBarrierExample3.java b/src/main/java/com/javaedge/concurrency/aqs/CyclicBarrierExample3.java
similarity index 95%
rename from concurrency/src/main/java/com/javaedge/concurrency/example/aqs/CyclicBarrierExample3.java
rename to src/main/java/com/javaedge/concurrency/aqs/CyclicBarrierExample3.java
index 90663bc..18f0926 100755
--- a/concurrency/src/main/java/com/javaedge/concurrency/example/aqs/CyclicBarrierExample3.java
+++ b/src/main/java/com/javaedge/concurrency/aqs/CyclicBarrierExample3.java
@@ -1,4 +1,4 @@
-package com.javaedge.concurrency.example.aqs;
+package main.java.com.javaedge.concurrency.aqs;
import lombok.extern.slf4j.Slf4j;
diff --git a/src/main/java/com/javaedge/concurrency/aqs/SampleLock.java b/src/main/java/com/javaedge/concurrency/aqs/SampleLock.java
new file mode 100644
index 0000000..b2334f1
--- /dev/null
+++ b/src/main/java/com/javaedge/concurrency/aqs/SampleLock.java
@@ -0,0 +1,25 @@
+package main.java.com.javaedge.concurrency.aqs;
+
+/**
+ * @author JavaEdge
+ * @date 2021/4/21
+ */
+class SampleLock {
+ volatile int state;
+
+ /**
+ * 加锁
+ */
+ void lock() {
+ // ...
+ state = 1;
+ }
+
+ /**
+ * 解锁
+ */
+ void unlock() {
+ // ...
+ state = 0;
+ }
+}
diff --git a/concurrency/src/main/java/com/javaedge/concurrency/example/aqs/SimpleLock.java b/src/main/java/com/javaedge/concurrency/aqs/SimpleLock.java
similarity index 92%
rename from concurrency/src/main/java/com/javaedge/concurrency/example/aqs/SimpleLock.java
rename to src/main/java/com/javaedge/concurrency/aqs/SimpleLock.java
index e82953c..86d9fdd 100644
--- a/concurrency/src/main/java/com/javaedge/concurrency/example/aqs/SimpleLock.java
+++ b/src/main/java/com/javaedge/concurrency/aqs/SimpleLock.java
@@ -1,3 +1,8 @@
+package main.java.com.javaedge.concurrency.aqs;
+
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.locks.AbstractQueuedSynchronizer;
+
public class SimpleLock {
private static class Sync extends AbstractQueuedSynchronizer {
@Override
diff --git a/src/main/java/com/javaedge/concurrency/aqs/semaphore/MicrowaveOvenPool.java b/src/main/java/com/javaedge/concurrency/aqs/semaphore/MicrowaveOvenPool.java
new file mode 100644
index 0000000..50ccf81
--- /dev/null
+++ b/src/main/java/com/javaedge/concurrency/aqs/semaphore/MicrowaveOvenPool.java
@@ -0,0 +1,87 @@
+package main.java.com.javaedge.concurrency.aqs.semaphore;
+
+import javax.validation.constraints.NotNull;
+import java.util.List;
+import java.util.Vector;
+import java.util.concurrent.Semaphore;
+import java.util.function.Function;
+
+/**
+ * @author JavaEdge
+ * @date 2021/4/22
+ */
+class Food {
+
+ public String name;
+
+ private long warmTime;
+
+ public Food(String name, long warmTime) {
+ this.name = name;
+ this.warmTime = warmTime;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public long getWarmTime() {
+ return warmTime;
+ }
+}
+
+class MicrowaveOven {
+
+ public String name;
+
+ public MicrowaveOven(String name) {
+ this.name = name;
+ }
+
+ public Food warm(Food food) {
+ long second = food.getWarmTime() * 1000;
+ try {
+ Thread.sleep(second);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+
+ System.out.println(String.format("%s warm %s %d seconds food.", name, food.getName(), food.getWarmTime()));
+ return food;
+ }
+
+ public String getName() {
+ return name;
+ }
+}
+
+/**
+ * @author JavaEdge
+ */
+public class MicrowaveOvenPool {
+
+ private List microwaveOvens;
+
+ private Semaphore semaphore;
+
+ public MicrowaveOvenPool(int size, @NotNull List microwaveOvens) {
+ this.microwaveOvens = new Vector<>(microwaveOvens);
+ this.semaphore = new Semaphore(size);
+ }
+
+ public Food exec(Function func) {
+ MicrowaveOven microwaveOven = null;
+ try {
+ semaphore.acquire();
+ microwaveOven = microwaveOvens.remove(0);
+ return func.apply(microwaveOven);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ } finally {
+ microwaveOvens.add(microwaveOven);
+ semaphore.release();
+ }
+ return null;
+ }
+
+}
diff --git a/src/main/java/com/javaedge/concurrency/aqs/semaphore/ObjPool.java b/src/main/java/com/javaedge/concurrency/aqs/semaphore/ObjPool.java
new file mode 100644
index 0000000..d1397cb
--- /dev/null
+++ b/src/main/java/com/javaedge/concurrency/aqs/semaphore/ObjPool.java
@@ -0,0 +1,71 @@
+package main.java.com.javaedge.concurrency.aqs.semaphore;
+
+import lombok.extern.slf4j.Slf4j;
+
+import java.util.List;
+import java.util.Vector;
+import java.util.concurrent.Semaphore;
+import java.util.function.Function;
+
+/**
+ * @author JavaEdge
+ * @date 2021/4/22
+ */
+@Slf4j
+public class ObjPool {
+
+ final List pool;
+
+ /**
+ * 用信号量实现限流器
+ */
+ final Semaphore sem;
+
+ ObjPool(int size, T t) {
+ // 使用线程安全的vector,因为信号量支持多个线程进入临界区
+ // 执行 add、remove 方法时可能有并发
+ pool = new Vector() {};
+ for (int i = 0; i < size; i++) {
+ pool.add(t);
+ }
+ sem = new Semaphore(size);
+ }
+
+ /**
+ * 利用对象池的对象,调用func
+ */
+ R exec(Function func) throws InterruptedException {
+ T t = null;
+ // 前10个线程调用acquire()方法,都能继续执行,相当于通过了信号灯
+ // 而其他线程则会阻塞在acquire()
+ sem.acquire();
+ try {
+ // 通过信号灯的线程,为每个线程分配一个对象 t
+ t = pool.remove(0);
+ // 执行回调方法
+ R apply = func.apply(t);
+ return apply;
+ } finally {
+ // 执行完回调后,释放对象
+ pool.add(t);
+
+ /**
+ * 更新信号量的计数器
+ * 如果此时信号量里计数器的值≤0,说明有线程在等待
+ * 此时会自动唤醒等待的线程
+ */
+ sem.release();
+ }
+ }
+
+ public static void main(String[] args) throws InterruptedException {
+ // 创建对象池
+ ObjPool pool = new ObjPool<>(10, 2L);
+ // 通过对象池获取t,之后执行
+ pool.exec(t -> {
+ log.info("t:{}", t);
+ return t.toString();
+ });
+ }
+}
+
diff --git a/concurrency/src/main/java/com/javaedge/concurrency/example/aqs/SemaphoreExample1.java b/src/main/java/com/javaedge/concurrency/aqs/semaphore/SemaphoreExample1.java
similarity index 83%
rename from concurrency/src/main/java/com/javaedge/concurrency/example/aqs/SemaphoreExample1.java
rename to src/main/java/com/javaedge/concurrency/aqs/semaphore/SemaphoreExample1.java
index 62c25e2..bcf563b 100755
--- a/concurrency/src/main/java/com/javaedge/concurrency/example/aqs/SemaphoreExample1.java
+++ b/src/main/java/com/javaedge/concurrency/aqs/semaphore/SemaphoreExample1.java
@@ -1,16 +1,18 @@
-package com.javaedge.concurrency.example.aqs;
+package main.java.com.javaedge.concurrency.aqs.semaphore;
import lombok.extern.slf4j.Slf4j;
-import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore;
+/**
+ * @author JavaEdge
+ */
@Slf4j
public class SemaphoreExample1 {
- private final static int threadCount = 20;
+ private final static int THREAD_COUNT = 20;
public static void main(String[] args) throws Exception {
@@ -18,7 +20,7 @@ public static void main(String[] args) throws Exception {
final Semaphore semaphore = new Semaphore(3);
- for (int i = 0; i < threadCount; i++) {
+ for (int i = 0; i < THREAD_COUNT; i++) {
final int threadNum = i;
exec.execute(() -> {
try {
diff --git a/concurrency/src/main/java/com/javaedge/concurrency/example/aqs/SemaphoreExample2.java b/src/main/java/com/javaedge/concurrency/aqs/semaphore/SemaphoreExample2.java
similarity index 94%
rename from concurrency/src/main/java/com/javaedge/concurrency/example/aqs/SemaphoreExample2.java
rename to src/main/java/com/javaedge/concurrency/aqs/semaphore/SemaphoreExample2.java
index 47ce2b4..b3c55b3 100755
--- a/concurrency/src/main/java/com/javaedge/concurrency/example/aqs/SemaphoreExample2.java
+++ b/src/main/java/com/javaedge/concurrency/aqs/semaphore/SemaphoreExample2.java
@@ -1,4 +1,4 @@
-package com.javaedge.concurrency.example.aqs;
+package main.java.com.javaedge.concurrency.aqs.semaphore;
import lombok.extern.slf4j.Slf4j;
diff --git a/concurrency/src/main/java/com/javaedge/concurrency/example/aqs/SemaphoreExample3.java b/src/main/java/com/javaedge/concurrency/aqs/semaphore/SemaphoreExample3.java
similarity index 92%
rename from concurrency/src/main/java/com/javaedge/concurrency/example/aqs/SemaphoreExample3.java
rename to src/main/java/com/javaedge/concurrency/aqs/semaphore/SemaphoreExample3.java
index 9c0ebb7..f9fe06d 100755
--- a/concurrency/src/main/java/com/javaedge/concurrency/example/aqs/SemaphoreExample3.java
+++ b/src/main/java/com/javaedge/concurrency/aqs/semaphore/SemaphoreExample3.java
@@ -1,11 +1,10 @@
-package com.javaedge.concurrency.example.aqs;
+package main.java.com.javaedge.concurrency.aqs.semaphore;
import lombok.extern.slf4j.Slf4j;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore;
-import java.util.concurrent.TimeUnit;
@Slf4j
public class SemaphoreExample3 {
diff --git a/concurrency/src/main/java/com/javaedge/concurrency/example/aqs/SemaphoreExample4.java b/src/main/java/com/javaedge/concurrency/aqs/semaphore/SemaphoreExample4.java
similarity index 95%
rename from concurrency/src/main/java/com/javaedge/concurrency/example/aqs/SemaphoreExample4.java
rename to src/main/java/com/javaedge/concurrency/aqs/semaphore/SemaphoreExample4.java
index c73e5af..29a3658 100755
--- a/concurrency/src/main/java/com/javaedge/concurrency/example/aqs/SemaphoreExample4.java
+++ b/src/main/java/com/javaedge/concurrency/aqs/semaphore/SemaphoreExample4.java
@@ -1,4 +1,4 @@
-package com.javaedge.concurrency.example.aqs;
+package main.java.com.javaedge.concurrency.aqs.semaphore;
import lombok.extern.slf4j.Slf4j;
diff --git a/src/main/java/com/javaedge/concurrency/aqs/semaphore/SemaphoreExample5.java b/src/main/java/com/javaedge/concurrency/aqs/semaphore/SemaphoreExample5.java
new file mode 100755
index 0000000..b462d07
--- /dev/null
+++ b/src/main/java/com/javaedge/concurrency/aqs/semaphore/SemaphoreExample5.java
@@ -0,0 +1,49 @@
+package main.java.com.javaedge.concurrency.aqs.semaphore;
+
+import lombok.extern.slf4j.Slf4j;
+
+import java.util.Queue;
+
+/**
+ * @author JavaEdge
+ */
+@Slf4j
+public class SemaphoreExample5 {
+ /**
+ * 计数器
+ */
+ int count;
+
+ /**
+ * 等待队列
+ */
+ Queue queue;
+
+ /**
+ * 初始化
+ *
+ * @param c
+ */
+ void Semaphore(int c){
+ this.count=c;
+ }
+
+ void down(){
+ this.count--;
+ if(this.count<0){
+ // 将当前线程插入等待队列
+ // 阻塞当前线程
+ }
+ }
+ void up(){
+ this.count++;
+ if(this.count<=0) {
+ // 移除等待队列中的某个线程t
+ // 唤醒线程t
+ }
+ }
+
+ public static void main(String[] args) {
+
+ }
+}
diff --git a/src/main/java/com/javaedge/concurrency/aqs/semaphore/SemaphoreExample6.java b/src/main/java/com/javaedge/concurrency/aqs/semaphore/SemaphoreExample6.java
new file mode 100755
index 0000000..ecdd6ba
--- /dev/null
+++ b/src/main/java/com/javaedge/concurrency/aqs/semaphore/SemaphoreExample6.java
@@ -0,0 +1,34 @@
+package main.java.com.javaedge.concurrency.aqs.semaphore;
+
+import java.util.concurrent.Semaphore;
+
+/**
+ * @author JavaEdge
+ */
+public class SemaphoreExample6 {
+
+ static int count;
+
+ /**
+ * 初始化信号量
+ */
+ static final Semaphore SEMAPHORE = new Semaphore(1);
+
+ /**
+ * 信号量保证互斥
+ */
+ static void add() throws InterruptedException {
+ // 进入临界区之前执行
+ SEMAPHORE.acquire();
+ try {
+ count += 1;
+ } finally {
+ // 退出临界区之前执行
+ SEMAPHORE.release();
+ }
+ }
+
+ public static void main(String[] args) throws InterruptedException {
+ add();
+ }
+}
diff --git a/concurrency/src/main/java/com/javaedge/concurrency/example/atomic/AtomicExample1.java b/src/main/java/com/javaedge/concurrency/atomic/AtomicExample1.java
similarity index 92%
rename from concurrency/src/main/java/com/javaedge/concurrency/example/atomic/AtomicExample1.java
rename to src/main/java/com/javaedge/concurrency/atomic/AtomicExample1.java
index eaba128..f309866 100755
--- a/concurrency/src/main/java/com/javaedge/concurrency/example/atomic/AtomicExample1.java
+++ b/src/main/java/com/javaedge/concurrency/atomic/AtomicExample1.java
@@ -1,6 +1,6 @@
-package com.javaedge.concurrency.example.atomic;
+package main.java.com.javaedge.concurrency.atomic;
-import com.javaedge.concurrency.annoations.ThreadSafe;
+import main.java.com.javaedge.concurrency.annoations.ThreadSafe;
import lombok.extern.slf4j.Slf4j;
import java.util.concurrent.CountDownLatch;
diff --git a/concurrency/src/main/java/com/javaedge/concurrency/example/atomic/AtomicExample2.java b/src/main/java/com/javaedge/concurrency/atomic/AtomicExample2.java
similarity index 92%
rename from concurrency/src/main/java/com/javaedge/concurrency/example/atomic/AtomicExample2.java
rename to src/main/java/com/javaedge/concurrency/atomic/AtomicExample2.java
index 452bfb4..42aed35 100755
--- a/concurrency/src/main/java/com/javaedge/concurrency/example/atomic/AtomicExample2.java
+++ b/src/main/java/com/javaedge/concurrency/atomic/AtomicExample2.java
@@ -1,6 +1,6 @@
-package com.javaedge.concurrency.example.atomic;
+package main.java.com.javaedge.concurrency.atomic;
-import com.javaedge.concurrency.annoations.ThreadSafe;
+import main.java.com.javaedge.concurrency.annoations.ThreadSafe;
import lombok.extern.slf4j.Slf4j;
import java.util.concurrent.CountDownLatch;
diff --git a/concurrency/src/main/java/com/javaedge/concurrency/example/atomic/AtomicExample3.java b/src/main/java/com/javaedge/concurrency/atomic/AtomicExample3.java
similarity index 92%
rename from concurrency/src/main/java/com/javaedge/concurrency/example/atomic/AtomicExample3.java
rename to src/main/java/com/javaedge/concurrency/atomic/AtomicExample3.java
index c6e20d3..ece69ca 100755
--- a/concurrency/src/main/java/com/javaedge/concurrency/example/atomic/AtomicExample3.java
+++ b/src/main/java/com/javaedge/concurrency/atomic/AtomicExample3.java
@@ -1,6 +1,6 @@
-package com.javaedge.concurrency.example.atomic;
+package main.java.com.javaedge.concurrency.atomic;
-import com.javaedge.concurrency.annoations.ThreadSafe;
+import main.java.com.javaedge.concurrency.annoations.ThreadSafe;
import lombok.extern.slf4j.Slf4j;
import java.util.concurrent.CountDownLatch;
diff --git a/concurrency/src/main/java/com/javaedge/concurrency/example/atomic/AtomicExample4.java b/src/main/java/com/javaedge/concurrency/atomic/AtomicExample4.java
similarity index 81%
rename from concurrency/src/main/java/com/javaedge/concurrency/example/atomic/AtomicExample4.java
rename to src/main/java/com/javaedge/concurrency/atomic/AtomicExample4.java
index d2b3c25..1238f30 100755
--- a/concurrency/src/main/java/com/javaedge/concurrency/example/atomic/AtomicExample4.java
+++ b/src/main/java/com/javaedge/concurrency/atomic/AtomicExample4.java
@@ -1,6 +1,6 @@
-package com.javaedge.concurrency.example.atomic;
+package main.java.com.javaedge.concurrency.atomic;
-import com.javaedge.concurrency.annoations.ThreadSafe;
+import main.java.com.javaedge.concurrency.annoations.ThreadSafe;
import lombok.extern.slf4j.Slf4j;
import java.util.concurrent.atomic.AtomicReference;
diff --git a/concurrency/src/main/java/com/javaedge/concurrency/example/atomic/AtomicExample5.java b/src/main/java/com/javaedge/concurrency/atomic/AtomicExample5.java
similarity index 87%
rename from concurrency/src/main/java/com/javaedge/concurrency/example/atomic/AtomicExample5.java
rename to src/main/java/com/javaedge/concurrency/atomic/AtomicExample5.java
index f4cc64c..0c37a22 100755
--- a/concurrency/src/main/java/com/javaedge/concurrency/example/atomic/AtomicExample5.java
+++ b/src/main/java/com/javaedge/concurrency/atomic/AtomicExample5.java
@@ -1,6 +1,6 @@
-package com.javaedge.concurrency.example.atomic;
+package main.java.com.javaedge.concurrency.atomic;
-import com.javaedge.concurrency.annoations.ThreadSafe;
+import main.java.com.javaedge.concurrency.annoations.ThreadSafe;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
diff --git a/concurrency/src/main/java/com/javaedge/concurrency/example/atomic/AtomicExample6.java b/src/main/java/com/javaedge/concurrency/atomic/AtomicExample6.java
similarity index 92%
rename from concurrency/src/main/java/com/javaedge/concurrency/example/atomic/AtomicExample6.java
rename to src/main/java/com/javaedge/concurrency/atomic/AtomicExample6.java
index 7d37d40..b5a4f7b 100755
--- a/concurrency/src/main/java/com/javaedge/concurrency/example/atomic/AtomicExample6.java
+++ b/src/main/java/com/javaedge/concurrency/atomic/AtomicExample6.java
@@ -1,6 +1,6 @@
-package com.javaedge.concurrency.example.atomic;
+package main.java.com.javaedge.concurrency.atomic;
-import com.javaedge.concurrency.annoations.ThreadSafe;
+import main.java.com.javaedge.concurrency.annoations.ThreadSafe;
import lombok.extern.slf4j.Slf4j;
import java.util.concurrent.CountDownLatch;
diff --git a/concurrency/src/main/java/com/javaedge/concurrency/example/atomic/AtomicTest.java b/src/main/java/com/javaedge/concurrency/atomic/AtomicTest.java
similarity index 92%
rename from concurrency/src/main/java/com/javaedge/concurrency/example/atomic/AtomicTest.java
rename to src/main/java/com/javaedge/concurrency/atomic/AtomicTest.java
index 5293174..8cbc04a 100755
--- a/concurrency/src/main/java/com/javaedge/concurrency/example/atomic/AtomicTest.java
+++ b/src/main/java/com/javaedge/concurrency/atomic/AtomicTest.java
@@ -1,4 +1,4 @@
-package com.javaedge.concurrency.example.atomic;
+package main.java.com.javaedge.concurrency.atomic;
import java.util.concurrent.atomic.AtomicInteger;
diff --git a/concurrency/src/main/java/com/javaedge/concurrency/example/atomic/LockCASDemo.java b/src/main/java/com/javaedge/concurrency/atomic/LockCASDemo.java
similarity index 97%
rename from concurrency/src/main/java/com/javaedge/concurrency/example/atomic/LockCASDemo.java
rename to src/main/java/com/javaedge/concurrency/atomic/LockCASDemo.java
index 9c0e3d8..e7c03d9 100644
--- a/concurrency/src/main/java/com/javaedge/concurrency/example/atomic/LockCASDemo.java
+++ b/src/main/java/com/javaedge/concurrency/atomic/LockCASDemo.java
@@ -1,4 +1,4 @@
-package com.javaedge.concurrency.example.atomic;
+package main.java.com.javaedge.concurrency.atomic;
import sun.misc.Unsafe;
diff --git a/concurrency/src/main/java/com/javaedge/concurrency/example/atomic/LongAccumulatorDemo.java b/src/main/java/com/javaedge/concurrency/atomic/LongAccumulatorDemo.java
similarity index 95%
rename from concurrency/src/main/java/com/javaedge/concurrency/example/atomic/LongAccumulatorDemo.java
rename to src/main/java/com/javaedge/concurrency/atomic/LongAccumulatorDemo.java
index dcdf135..d78dc47 100755
--- a/concurrency/src/main/java/com/javaedge/concurrency/example/atomic/LongAccumulatorDemo.java
+++ b/src/main/java/com/javaedge/concurrency/atomic/LongAccumulatorDemo.java
@@ -1,4 +1,4 @@
-package com.javaedge.concurrency.example.atomic;
+package main.java.com.javaedge.concurrency.atomic;
import java.util.concurrent.atomic.LongAccumulator;
import java.util.function.LongBinaryOperator;
diff --git a/concurrency/src/main/java/com/javaedge/concurrency/example/atomic/LongAdderDemo.java b/src/main/java/com/javaedge/concurrency/atomic/LongAdderDemo.java
similarity index 97%
rename from concurrency/src/main/java/com/javaedge/concurrency/example/atomic/LongAdderDemo.java
rename to src/main/java/com/javaedge/concurrency/atomic/LongAdderDemo.java
index 16927b1..b415904 100755
--- a/concurrency/src/main/java/com/javaedge/concurrency/example/atomic/LongAdderDemo.java
+++ b/src/main/java/com/javaedge/concurrency/atomic/LongAdderDemo.java
@@ -1,4 +1,4 @@
-package com.javaedge.concurrency.example.atomic;
+package main.java.com.javaedge.concurrency.atomic;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.atomic.LongAdder;
diff --git a/concurrency/src/main/java/com/javaedge/concurrency/example/cache/CacheController.java b/src/main/java/com/javaedge/concurrency/cache/CacheController.java
similarity index 94%
rename from concurrency/src/main/java/com/javaedge/concurrency/example/cache/CacheController.java
rename to src/main/java/com/javaedge/concurrency/cache/CacheController.java
index 1eb5898..321d024 100755
--- a/concurrency/src/main/java/com/javaedge/concurrency/example/cache/CacheController.java
+++ b/src/main/java/com/javaedge/concurrency/cache/CacheController.java
@@ -1,4 +1,4 @@
-package com.javaedge.concurrency.example.cache;
+package main.java.com.javaedge.concurrency.cache;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
diff --git a/concurrency/src/main/java/com/javaedge/concurrency/example/cache/GuavaCacheExample1.java b/src/main/java/com/javaedge/concurrency/cache/GuavaCacheExample1.java
similarity index 97%
rename from concurrency/src/main/java/com/javaedge/concurrency/example/cache/GuavaCacheExample1.java
rename to src/main/java/com/javaedge/concurrency/cache/GuavaCacheExample1.java
index e66ca99..09d2bad 100755
--- a/concurrency/src/main/java/com/javaedge/concurrency/example/cache/GuavaCacheExample1.java
+++ b/src/main/java/com/javaedge/concurrency/cache/GuavaCacheExample1.java
@@ -1,4 +1,4 @@
-package com.javaedge.concurrency.example.cache;
+package com.javaedge.concurrency.cache;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
diff --git a/concurrency/src/main/java/com/javaedge/concurrency/example/cache/GuavaCacheExample2.java b/src/main/java/com/javaedge/concurrency/cache/GuavaCacheExample2.java
similarity index 97%
rename from concurrency/src/main/java/com/javaedge/concurrency/example/cache/GuavaCacheExample2.java
rename to src/main/java/com/javaedge/concurrency/cache/GuavaCacheExample2.java
index 9c192ab..5548124 100755
--- a/concurrency/src/main/java/com/javaedge/concurrency/example/cache/GuavaCacheExample2.java
+++ b/src/main/java/com/javaedge/concurrency/cache/GuavaCacheExample2.java
@@ -1,4 +1,4 @@
-package com.javaedge.concurrency.example.cache;
+package main.java.com.javaedge.concurrency.cache;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
diff --git a/concurrency/src/main/java/com/javaedge/concurrency/example/cache/RedisClient.java b/src/main/java/com/javaedge/concurrency/cache/RedisClient.java
similarity index 94%
rename from concurrency/src/main/java/com/javaedge/concurrency/example/cache/RedisClient.java
rename to src/main/java/com/javaedge/concurrency/cache/RedisClient.java
index cf12169..d985089 100755
--- a/concurrency/src/main/java/com/javaedge/concurrency/example/cache/RedisClient.java
+++ b/src/main/java/com/javaedge/concurrency/cache/RedisClient.java
@@ -1,4 +1,4 @@
-package com.javaedge.concurrency.example.cache;
+package main.java.com.javaedge.concurrency.cache;
import org.springframework.stereotype.Component;
import redis.clients.jedis.Jedis;
diff --git a/concurrency/src/main/java/com/javaedge/concurrency/example/cache/RedisConfig.java b/src/main/java/com/javaedge/concurrency/cache/RedisConfig.java
similarity index 90%
rename from concurrency/src/main/java/com/javaedge/concurrency/example/cache/RedisConfig.java
rename to src/main/java/com/javaedge/concurrency/cache/RedisConfig.java
index 1100ff7..7b7aaed 100755
--- a/concurrency/src/main/java/com/javaedge/concurrency/example/cache/RedisConfig.java
+++ b/src/main/java/com/javaedge/concurrency/cache/RedisConfig.java
@@ -1,4 +1,4 @@
-package com.javaedge.concurrency.example.cache;
+package main.java.com.javaedge.concurrency.cache;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
diff --git a/concurrency/src/main/java/com/javaedge/concurrency/cas/demo/ConcurrentStack.java b/src/main/java/com/javaedge/concurrency/cas/demo/ConcurrentStack.java
similarity index 96%
rename from concurrency/src/main/java/com/javaedge/concurrency/cas/demo/ConcurrentStack.java
rename to src/main/java/com/javaedge/concurrency/cas/demo/ConcurrentStack.java
index 49129e3..97e53e9 100755
--- a/concurrency/src/main/java/com/javaedge/concurrency/cas/demo/ConcurrentStack.java
+++ b/src/main/java/com/javaedge/concurrency/cas/demo/ConcurrentStack.java
@@ -1,4 +1,4 @@
-package com.javaedge.concurrency.cas.demo;
+package main.java.com.javaedge.concurrency.cas.demo;
import com.javaedge.concurrency.cas.demo.Node;
diff --git a/concurrency/src/main/java/com/javaedge/concurrency/cas/demo/Node.java b/src/main/java/com/javaedge/concurrency/cas/demo/Node.java
similarity index 85%
rename from concurrency/src/main/java/com/javaedge/concurrency/cas/demo/Node.java
rename to src/main/java/com/javaedge/concurrency/cas/demo/Node.java
index 8efedc0..14a1fa4 100755
--- a/concurrency/src/main/java/com/javaedge/concurrency/cas/demo/Node.java
+++ b/src/main/java/com/javaedge/concurrency/cas/demo/Node.java
@@ -1,4 +1,4 @@
-package com.javaedge.concurrency.cas.demo;
+package main.java.com.javaedge.concurrency.cas.demo;
/**
* 存储在栈里面元素 -- 对象
diff --git a/concurrency/src/main/java/com/javaedge/concurrency/cas/demo/Stack.java b/src/main/java/com/javaedge/concurrency/cas/demo/Stack.java
similarity index 96%
rename from concurrency/src/main/java/com/javaedge/concurrency/cas/demo/Stack.java
rename to src/main/java/com/javaedge/concurrency/cas/demo/Stack.java
index f118e6c..36b908e 100644
--- a/concurrency/src/main/java/com/javaedge/concurrency/cas/demo/Stack.java
+++ b/src/main/java/com/javaedge/concurrency/cas/demo/Stack.java
@@ -1,4 +1,4 @@
-package com.javaedge.concurrency.cas.demo;
+package main.java.com.javaedge.concurrency.cas.demo;
import java.util.concurrent.TimeUnit;
diff --git a/concurrency/src/main/java/com/javaedge/concurrency/cas/demo/Test.java b/src/main/java/com/javaedge/concurrency/cas/demo/Test.java
similarity index 92%
rename from concurrency/src/main/java/com/javaedge/concurrency/cas/demo/Test.java
rename to src/main/java/com/javaedge/concurrency/cas/demo/Test.java
index fc6a42d..b90d2ac 100755
--- a/concurrency/src/main/java/com/javaedge/concurrency/cas/demo/Test.java
+++ b/src/main/java/com/javaedge/concurrency/cas/demo/Test.java
@@ -1,7 +1,7 @@
-package com.javaedge.concurrency.cas.demo;
+package main.java.com.javaedge.concurrency.cas.demo;
import com.javaedge.concurrency.cas.demo.Node;
-import com.javaedge.concurrency.cas.demo.Stack;
+import main.java.com.javaedge.concurrency.cas.demo.Stack;
public class Test {
public static void main(String[] args) throws InterruptedException {
diff --git a/src/main/java/com/javaedge/concurrency/common/Nap.java b/src/main/java/com/javaedge/concurrency/common/Nap.java
new file mode 100644
index 0000000..adb7c4c
--- /dev/null
+++ b/src/main/java/com/javaedge/concurrency/common/Nap.java
@@ -0,0 +1,23 @@
+package main.java.com.javaedge.concurrency.common;
+
+import java.util.concurrent.TimeUnit;
+
+/**
+ * @author JavaEdge
+ */
+public class Nap {
+
+ // Seconds
+ public Nap(double t) {
+ try {
+ TimeUnit.MILLISECONDS.sleep((int) (1000 * t));
+ } catch (InterruptedException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ public Nap(double t, String msg) {
+ this(t);
+ System.out.println(msg);
+ }
+}
diff --git a/concurrency/src/main/java/com/javaedge/concurrency/common/Timer.java b/src/main/java/com/javaedge/concurrency/common/Timer.java
similarity index 70%
rename from concurrency/src/main/java/com/javaedge/concurrency/common/Timer.java
rename to src/main/java/com/javaedge/concurrency/common/Timer.java
index c6a857d..77a3da4 100644
--- a/concurrency/src/main/java/com/javaedge/concurrency/common/Timer.java
+++ b/src/main/java/com/javaedge/concurrency/common/Timer.java
@@ -2,13 +2,13 @@
// (c)2017 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information.
-package com.javaedge.concurrency.common;
+package main.java.com.javaedge.concurrency.common;
import static java.util.concurrent.TimeUnit.NANOSECONDS;
public class Timer {
- private long start = System.nanoTime();
- public long duration() {
+ private static long start = System.nanoTime();
+ public static long duration() {
return NANOSECONDS.toMillis(
System.nanoTime() - start);
}
@@ -17,4 +17,8 @@ public static long duration(Runnable test) {
test.run();
return timer.duration();
}
+
+ public static void main(String[] args) {
+ duration();
+ }
}
diff --git a/concurrency/src/main/java/com/javaedge/concurrency/common/closure/ThreadClosure.java b/src/main/java/com/javaedge/concurrency/common/closure/ThreadClosure.java
similarity index 95%
rename from concurrency/src/main/java/com/javaedge/concurrency/common/closure/ThreadClosure.java
rename to src/main/java/com/javaedge/concurrency/common/closure/ThreadClosure.java
index d803764..eecd77a 100644
--- a/concurrency/src/main/java/com/javaedge/concurrency/common/closure/ThreadClosure.java
+++ b/src/main/java/com/javaedge/concurrency/common/closure/ThreadClosure.java
@@ -1,4 +1,4 @@
-package com.javaedge.concurrency.common.closure;
+package main.java.com.javaedge.concurrency.common.closure;
import org.testng.annotations.Test;
diff --git a/concurrency/src/main/java/com/javaedge/concurrency/common/communication/ThreadCommunication.java b/src/main/java/com/javaedge/concurrency/common/communication/ThreadCommunication.java
similarity index 94%
rename from concurrency/src/main/java/com/javaedge/concurrency/common/communication/ThreadCommunication.java
rename to src/main/java/com/javaedge/concurrency/common/communication/ThreadCommunication.java
index 2203198..ba94398 100644
--- a/concurrency/src/main/java/com/javaedge/concurrency/common/communication/ThreadCommunication.java
+++ b/src/main/java/com/javaedge/concurrency/common/communication/ThreadCommunication.java
@@ -1,4 +1,4 @@
-package com.javaedge.concurrency.common.communication;
+package main.java.com.javaedge.concurrency.common.communication;
import java.util.concurrent.locks.LockSupport;
@@ -6,6 +6,7 @@
/**
* 三种线程协作通信的方式:suspend/resume、wait/notify、park/unpark
+ * 原理文档:https://javaedge.blog.csdn.net/article/details/102345871
*
* @author JavaEdge
* @date 2019/10/8
@@ -40,7 +41,8 @@ public void suspendResumeTest() throws Exception {
}
/**
- * 死锁的suspend/resume。 suspend并不会像wait一样释放锁,容易写出死锁代码
+ * 死锁的suspend/resume
+ * suspend并不会像wait一样释放锁,容易写出死锁代码
*/
@Test
public void suspendResumeDeadLockTest() throws Exception {
@@ -108,6 +110,7 @@ public void waitNotifyTest() throws Exception {
try {
System.out.println("1、进入等待");
this.wait();
+ System.out.println("wait 结束!");
} catch (InterruptedException e) {
e.printStackTrace();
}
@@ -164,14 +167,15 @@ public void waitNotifyDeadLockTest() throws Exception {
public void parkUnparkTest() throws Exception {
// 启动线程
Thread consumerThread = new Thread(() -> {
- if (bunShop == null) { // 如果没包子,则进入等待
+ // 如果没包子,则进入等待
+ if (bunShop == null) {
System.out.println("1、进入等待");
LockSupport.park();
}
System.out.println("2、买到包子,回家");
});
consumerThread.start();
- // 3秒之后,生产一个包子
+ // 3s后,生产一个包子
Thread.sleep(3000L);
bunShop = new Object();
LockSupport.unpark(consumerThread);
diff --git a/concurrency/src/main/java/com/javaedge/concurrency/common/state/ThreadState.java b/src/main/java/com/javaedge/concurrency/common/state/ThreadState.java
similarity index 97%
rename from concurrency/src/main/java/com/javaedge/concurrency/common/state/ThreadState.java
rename to src/main/java/com/javaedge/concurrency/common/state/ThreadState.java
index e5172af..f123ad2 100644
--- a/concurrency/src/main/java/com/javaedge/concurrency/common/state/ThreadState.java
+++ b/src/main/java/com/javaedge/concurrency/common/state/ThreadState.java
@@ -1,7 +1,7 @@
-package com.javaedge.concurrency.common.state;
+package main.java.com.javaedge.concurrency.common.state;
/**
- * 多线程运行状态切换示例
+ * 多线程运行状态切换
*
* @author JavaEdge
* @date 2019/8/26
diff --git a/concurrency/src/main/java/com/javaedge/concurrency/common/stop/FlagStopThread.java b/src/main/java/com/javaedge/concurrency/common/stop/FlagStopThread.java
similarity index 84%
rename from concurrency/src/main/java/com/javaedge/concurrency/common/stop/FlagStopThread.java
rename to src/main/java/com/javaedge/concurrency/common/stop/FlagStopThread.java
index 8cfe920..7201e65 100644
--- a/concurrency/src/main/java/com/javaedge/concurrency/common/stop/FlagStopThread.java
+++ b/src/main/java/com/javaedge/concurrency/common/stop/FlagStopThread.java
@@ -1,4 +1,4 @@
-package com.javaedge.concurrency.common.stop;
+package main.java.com.javaedge.concurrency.common.stop;
/**
* 通过状态位来判断
@@ -7,6 +7,7 @@
* @date 2019/8/29
*/
public class FlagStopThread extends Thread {
+
public volatile static boolean flag = true;
public static void main(String[] args) throws InterruptedException {
@@ -20,7 +21,7 @@ public static void main(String[] args) throws InterruptedException {
e.printStackTrace();
}
}).start();
- // 3秒之后,将状态标志改为False,代表不继续运行
+ // 3s后,将状态标志改为False,代表不继续运行
Thread.sleep(3000L);
flag = false;
System.out.println("程序运行结束");
diff --git a/src/main/java/com/javaedge/concurrency/common/stop/PrimeGenerator.java b/src/main/java/com/javaedge/concurrency/common/stop/PrimeGenerator.java
new file mode 100644
index 0000000..9ac8877
--- /dev/null
+++ b/src/main/java/com/javaedge/concurrency/common/stop/PrimeGenerator.java
@@ -0,0 +1,70 @@
+package main.java.com.javaedge.concurrency.common.stop;
+
+import main.java.com.javaedge.concurrency.annoations.ThreadSafe;
+import lombok.extern.slf4j.Slf4j;
+
+import javax.annotation.concurrent.GuardedBy;
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+
+import static java.util.concurrent.TimeUnit.SECONDS;
+
+/**
+ * @author JavaEdge
+ * @date 2021/5/8
+ */
+@ThreadSafe
+@Slf4j
+public class PrimeGenerator implements Runnable {
+ private static ExecutorService exec = Executors.newCachedThreadPool();
+
+ @GuardedBy("this")
+ private final List primes = new ArrayList<>();
+ private volatile boolean cancelled;
+
+ @Override
+ public void run() {
+ BigInteger p = BigInteger.ONE;
+ // 主循环在搜索下一个素数之前会首先检查取消标志
+ while (!cancelled) {
+ // 持续枚举素数,直到被取消
+ p = p.nextProbablePrime();
+ synchronized (this) {
+ primes.add(p);
+ }
+ }
+ }
+
+ public void cancel() {
+ cancelled = true;
+ }
+
+ public synchronized List get() {
+ return new ArrayList<>(primes);
+ }
+
+ static List aSecondOfPrimes() throws InterruptedException {
+ PrimeGenerator generator = new PrimeGenerator();
+ exec.execute(generator);
+ try {
+
+ /**
+ * 素数生成器通常并不会刚好在运行 1s 后停止,因为在 请求取消的时刻 和 run方法中循环执行下一次检查 之间可能存在延迟
+ */
+ SECONDS.sleep(1);
+ } finally {
+ // cancel方法由finally块调用,从而确保即使在调用sleep时被中断,也能取消素数生成器的执行
+ // 如果cancel没有被调用,那么搜索素数的线程将永远运行下去,不断消耗CPU时钟周期,且使得JVM不能正常退出
+ generator.cancel();
+ }
+ return generator.get();
+ }
+
+ public static void main(String[] args) throws InterruptedException {
+ log.info("result:{}", aSecondOfPrimes());
+ }
+}
+
diff --git a/concurrency/src/main/java/com/javaedge/concurrency/common/stop/StopThread.java b/src/main/java/com/javaedge/concurrency/common/stop/StopThread.java
similarity index 73%
rename from concurrency/src/main/java/com/javaedge/concurrency/common/stop/StopThread.java
rename to src/main/java/com/javaedge/concurrency/common/stop/StopThread.java
index 3dfbd36..501b5b0 100755
--- a/concurrency/src/main/java/com/javaedge/concurrency/common/stop/StopThread.java
+++ b/src/main/java/com/javaedge/concurrency/common/stop/StopThread.java
@@ -1,8 +1,6 @@
-package com.javaedge.concurrency.common.stop;
+package main.java.com.javaedge.concurrency.common.stop;
/**
- * 线程stop强制性中止,破坏线程安全的示例
- *
* @author JavaEdge
* @date 2019/8/26
*/
@@ -15,7 +13,7 @@ public void run() {
// 增加同步锁,确保线程安全
++i;
try {
- // 休眠10秒,模拟耗时操作
+ // 休眠10s,模拟耗时操作
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
@@ -24,9 +22,6 @@ public void run() {
}
}
- /**
- * 打印i和j
- */
public void print() {
System.out.println("i=" + i + " j=" + j);
}
diff --git a/concurrency/src/main/java/com/javaedge/concurrency/common/stop/ThreadStop.java b/src/main/java/com/javaedge/concurrency/common/stop/ThreadStop.java
similarity index 65%
rename from concurrency/src/main/java/com/javaedge/concurrency/common/stop/ThreadStop.java
rename to src/main/java/com/javaedge/concurrency/common/stop/ThreadStop.java
index 288e5a9..6fe9aca 100644
--- a/concurrency/src/main/java/com/javaedge/concurrency/common/stop/ThreadStop.java
+++ b/src/main/java/com/javaedge/concurrency/common/stop/ThreadStop.java
@@ -1,8 +1,6 @@
-package com.javaedge.concurrency.common.stop;
+package main.java.com.javaedge.concurrency.common.stop;
/**
- * 线程stop强制性中止,破坏线程安全的示例
- *
* @author JavaEdge
* @date 2019/8/26
*/
@@ -12,9 +10,11 @@ public static void main(String[] args) throws InterruptedException {
thread.start();
// 休眠1秒,确保i变量自增成功
Thread.sleep(1000);
- // 暂停线程
- // thread.stop(); // 错误的终止
- thread.interrupt(); // 正确的终止
+ // 错误的终止 线程stop强制性中止,破坏线程安全
+// thread.stop();
+
+ // 正确的终止
+ thread.interrupt();
while (thread.isAlive()) {
// 确保线程已经终止
} // 输出结果
diff --git a/concurrency/src/main/java/com/javaedge/concurrency/common/volatiletest/VisibilityDemo.java b/src/main/java/com/javaedge/concurrency/common/volatiletest/VisibilityDemo.java
similarity index 96%
rename from concurrency/src/main/java/com/javaedge/concurrency/common/volatiletest/VisibilityDemo.java
rename to src/main/java/com/javaedge/concurrency/common/volatiletest/VisibilityDemo.java
index 085d1d8..5247ab5 100644
--- a/concurrency/src/main/java/com/javaedge/concurrency/common/volatiletest/VisibilityDemo.java
+++ b/src/main/java/com/javaedge/concurrency/common/volatiletest/VisibilityDemo.java
@@ -1,4 +1,4 @@
-package com.javaedge.concurrency.common.volatiletest;
+package main.java.com.javaedge.concurrency.common.volatiletest;
/**
* @author JavaEdge
diff --git a/concurrency/src/main/java/com/javaedge/concurrency/common/volatiletest/VisibilityDemo1.java b/src/main/java/com/javaedge/concurrency/common/volatiletest/VisibilityDemo1.java
similarity index 93%
rename from concurrency/src/main/java/com/javaedge/concurrency/common/volatiletest/VisibilityDemo1.java
rename to src/main/java/com/javaedge/concurrency/common/volatiletest/VisibilityDemo1.java
index 19169ba..8956eb2 100755
--- a/concurrency/src/main/java/com/javaedge/concurrency/common/volatiletest/VisibilityDemo1.java
+++ b/src/main/java/com/javaedge/concurrency/common/volatiletest/VisibilityDemo1.java
@@ -1,4 +1,4 @@
-package com.javaedge.concurrency.common.volatiletest;
+package main.java.com.javaedge.concurrency.common.volatiletest;
import java.util.concurrent.TimeUnit;
diff --git a/concurrency/src/main/java/com/javaedge/concurrency/common/volatiletest/VisibilityDemo2.java b/src/main/java/com/javaedge/concurrency/common/volatiletest/VisibilityDemo2.java
similarity index 94%
rename from concurrency/src/main/java/com/javaedge/concurrency/common/volatiletest/VisibilityDemo2.java
rename to src/main/java/com/javaedge/concurrency/common/volatiletest/VisibilityDemo2.java
index edf43d4..04bb23a 100755
--- a/concurrency/src/main/java/com/javaedge/concurrency/common/volatiletest/VisibilityDemo2.java
+++ b/src/main/java/com/javaedge/concurrency/common/volatiletest/VisibilityDemo2.java
@@ -1,4 +1,4 @@
-package com.javaedge.concurrency.common.volatiletest;
+package main.java.com.javaedge.concurrency.common.volatiletest;
import java.util.concurrent.TimeUnit;
diff --git a/concurrency/src/main/java/com/javaedge/concurrency/example/commonUnsafe/ArrayListExample.java b/src/main/java/com/javaedge/concurrency/commonunsafe/ArrayListExample.java
similarity index 96%
rename from concurrency/src/main/java/com/javaedge/concurrency/example/commonUnsafe/ArrayListExample.java
rename to src/main/java/com/javaedge/concurrency/commonunsafe/ArrayListExample.java
index b6c4b04..29541aa 100755
--- a/concurrency/src/main/java/com/javaedge/concurrency/example/commonUnsafe/ArrayListExample.java
+++ b/src/main/java/com/javaedge/concurrency/commonunsafe/ArrayListExample.java
@@ -1,4 +1,4 @@
-package com.javaedge.concurrency.example.commonUnsafe;
+package main.java.com.javaedge.concurrency.commonunsafe;
import com.javaedge.concurrency.annoations.NotThreadSafe;
import lombok.extern.slf4j.Slf4j;
diff --git a/concurrency/src/main/java/com/javaedge/concurrency/example/commonUnsafe/DateFormatExample1.java b/src/main/java/com/javaedge/concurrency/commonunsafe/DateFormatExample1.java
similarity index 96%
rename from concurrency/src/main/java/com/javaedge/concurrency/example/commonUnsafe/DateFormatExample1.java
rename to src/main/java/com/javaedge/concurrency/commonunsafe/DateFormatExample1.java
index e560455..bceba91 100755
--- a/concurrency/src/main/java/com/javaedge/concurrency/example/commonUnsafe/DateFormatExample1.java
+++ b/src/main/java/com/javaedge/concurrency/commonunsafe/DateFormatExample1.java
@@ -1,4 +1,4 @@
-package com.javaedge.concurrency.example.commonUnsafe;
+package main.java.com.javaedge.concurrency.commonunsafe;
import com.javaedge.concurrency.annoations.NotThreadSafe;
import lombok.extern.slf4j.Slf4j;
diff --git a/concurrency/src/main/java/com/javaedge/concurrency/example/commonUnsafe/DateFormatExample2.java b/src/main/java/com/javaedge/concurrency/commonunsafe/DateFormatExample2.java
similarity index 96%
rename from concurrency/src/main/java/com/javaedge/concurrency/example/commonUnsafe/DateFormatExample2.java
rename to src/main/java/com/javaedge/concurrency/commonunsafe/DateFormatExample2.java
index cfdcad9..809e505 100755
--- a/concurrency/src/main/java/com/javaedge/concurrency/example/commonUnsafe/DateFormatExample2.java
+++ b/src/main/java/com/javaedge/concurrency/commonunsafe/DateFormatExample2.java
@@ -1,4 +1,4 @@
-package com.javaedge.concurrency.example.commonUnsafe;
+package main.java.com.javaedge.concurrency.commonunsafe;
import com.javaedge.concurrency.annoations.ThreadSafe;
import lombok.extern.slf4j.Slf4j;
diff --git a/concurrency/src/main/java/com/javaedge/concurrency/example/commonUnsafe/DateFormatExample3.java b/src/main/java/com/javaedge/concurrency/commonunsafe/DateFormatExample3.java
similarity index 96%
rename from concurrency/src/main/java/com/javaedge/concurrency/example/commonUnsafe/DateFormatExample3.java
rename to src/main/java/com/javaedge/concurrency/commonunsafe/DateFormatExample3.java
index c23d5fb..8057e44 100755
--- a/concurrency/src/main/java/com/javaedge/concurrency/example/commonUnsafe/DateFormatExample3.java
+++ b/src/main/java/com/javaedge/concurrency/commonunsafe/DateFormatExample3.java
@@ -1,4 +1,4 @@
-package com.javaedge.concurrency.example.commonUnsafe;
+package main.java.com.javaedge.concurrency.commonunsafe;
import com.javaedge.concurrency.annoations.ThreadSafe;
import lombok.extern.slf4j.Slf4j;
diff --git a/concurrency/src/main/java/com/javaedge/concurrency/example/commonUnsafe/HashMapExample.java b/src/main/java/com/javaedge/concurrency/commonunsafe/HashMapExample.java
similarity index 96%
rename from concurrency/src/main/java/com/javaedge/concurrency/example/commonUnsafe/HashMapExample.java
rename to src/main/java/com/javaedge/concurrency/commonunsafe/HashMapExample.java
index 0220ee6..b6eb68b 100755
--- a/concurrency/src/main/java/com/javaedge/concurrency/example/commonUnsafe/HashMapExample.java
+++ b/src/main/java/com/javaedge/concurrency/commonunsafe/HashMapExample.java
@@ -1,4 +1,4 @@
-package com.javaedge.concurrency.example.commonUnsafe;
+package main.java.com.javaedge.concurrency.commonunsafe;
import com.javaedge.concurrency.annoations.NotThreadSafe;
import lombok.extern.slf4j.Slf4j;
diff --git a/concurrency/src/main/java/com/javaedge/concurrency/example/commonUnsafe/HashSetExample.java b/src/main/java/com/javaedge/concurrency/commonunsafe/HashSetExample.java
similarity index 96%
rename from concurrency/src/main/java/com/javaedge/concurrency/example/commonUnsafe/HashSetExample.java
rename to src/main/java/com/javaedge/concurrency/commonunsafe/HashSetExample.java
index 8d1c90c..69b9a57 100755
--- a/concurrency/src/main/java/com/javaedge/concurrency/example/commonUnsafe/HashSetExample.java
+++ b/src/main/java/com/javaedge/concurrency/commonunsafe/HashSetExample.java
@@ -1,4 +1,4 @@
-package com.javaedge.concurrency.example.commonUnsafe;
+package main.java.com.javaedge.concurrency.commonunsafe;
import com.javaedge.concurrency.annoations.NotThreadSafe;
import lombok.extern.slf4j.Slf4j;
diff --git a/concurrency/src/main/java/com/javaedge/concurrency/example/commonUnsafe/StringExample1.java b/src/main/java/com/javaedge/concurrency/commonunsafe/StringExample1.java
similarity index 96%
rename from concurrency/src/main/java/com/javaedge/concurrency/example/commonUnsafe/StringExample1.java
rename to src/main/java/com/javaedge/concurrency/commonunsafe/StringExample1.java
index fc41eb8..e445ff8 100755
--- a/concurrency/src/main/java/com/javaedge/concurrency/example/commonUnsafe/StringExample1.java
+++ b/src/main/java/com/javaedge/concurrency/commonunsafe/StringExample1.java
@@ -1,4 +1,4 @@
-package com.javaedge.concurrency.example.commonUnsafe;
+package main.java.com.javaedge.concurrency.commonunsafe;
import com.javaedge.concurrency.annoations.NotThreadSafe;
import lombok.extern.slf4j.Slf4j;
diff --git a/concurrency/src/main/java/com/javaedge/concurrency/example/commonUnsafe/StringExample2.java b/src/main/java/com/javaedge/concurrency/commonunsafe/StringExample2.java
similarity index 94%
rename from concurrency/src/main/java/com/javaedge/concurrency/example/commonUnsafe/StringExample2.java
rename to src/main/java/com/javaedge/concurrency/commonunsafe/StringExample2.java
index 98c21ef..00594c1 100755
--- a/concurrency/src/main/java/com/javaedge/concurrency/example/commonUnsafe/StringExample2.java
+++ b/src/main/java/com/javaedge/concurrency/commonunsafe/StringExample2.java
@@ -1,4 +1,4 @@
-package com.javaedge.concurrency.example.commonUnsafe;
+package main.java.com.javaedge.concurrency.commonunsafe;
import com.javaedge.concurrency.annoations.ThreadSafe;
import lombok.extern.slf4j.Slf4j;
@@ -8,6 +8,9 @@
import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore;
+/**
+ * @author JavaEdge
+ */
@Slf4j
@ThreadSafe
public class StringExample2 {
diff --git a/concurrency/src/main/java/com/javaedge/concurrency/example/concurrent/ConcurrentHashMapExample.java b/src/main/java/com/javaedge/concurrency/concurrent/ConcurrentHashMapExample.java
similarity index 96%
rename from concurrency/src/main/java/com/javaedge/concurrency/example/concurrent/ConcurrentHashMapExample.java
rename to src/main/java/com/javaedge/concurrency/concurrent/ConcurrentHashMapExample.java
index b8c30c8..4a7d217 100755
--- a/concurrency/src/main/java/com/javaedge/concurrency/example/concurrent/ConcurrentHashMapExample.java
+++ b/src/main/java/com/javaedge/concurrency/concurrent/ConcurrentHashMapExample.java
@@ -1,4 +1,4 @@
-package com.javaedge.concurrency.example.concurrent;
+package main.java.com.javaedge.concurrency.concurrent;
import com.javaedge.concurrency.annoations.ThreadSafe;
import lombok.extern.slf4j.Slf4j;
diff --git a/concurrency/src/main/java/com/javaedge/concurrency/example/concurrent/ConcurrentSkipListMapExample.java b/src/main/java/com/javaedge/concurrency/concurrent/ConcurrentSkipListMapExample.java
similarity index 96%
rename from concurrency/src/main/java/com/javaedge/concurrency/example/concurrent/ConcurrentSkipListMapExample.java
rename to src/main/java/com/javaedge/concurrency/concurrent/ConcurrentSkipListMapExample.java
index b81407e..1d39bd0 100755
--- a/concurrency/src/main/java/com/javaedge/concurrency/example/concurrent/ConcurrentSkipListMapExample.java
+++ b/src/main/java/com/javaedge/concurrency/concurrent/ConcurrentSkipListMapExample.java
@@ -1,4 +1,4 @@
-package com.javaedge.concurrency.example.concurrent;
+package main.java.com.javaedge.concurrency.concurrent;
import com.javaedge.concurrency.annoations.ThreadSafe;
import lombok.extern.slf4j.Slf4j;
diff --git a/concurrency/src/main/java/com/javaedge/concurrency/example/concurrent/ConcurrentSkipListSetExample.java b/src/main/java/com/javaedge/concurrency/concurrent/ConcurrentSkipListSetExample.java
similarity index 96%
rename from concurrency/src/main/java/com/javaedge/concurrency/example/concurrent/ConcurrentSkipListSetExample.java
rename to src/main/java/com/javaedge/concurrency/concurrent/ConcurrentSkipListSetExample.java
index 1a1833c..b197d1b 100755
--- a/concurrency/src/main/java/com/javaedge/concurrency/example/concurrent/ConcurrentSkipListSetExample.java
+++ b/src/main/java/com/javaedge/concurrency/concurrent/ConcurrentSkipListSetExample.java
@@ -1,4 +1,4 @@
-package com.javaedge.concurrency.example.concurrent;
+package main.java.com.javaedge.concurrency.concurrent;
import com.javaedge.concurrency.annoations.ThreadSafe;
import lombok.extern.slf4j.Slf4j;
diff --git a/concurrency/src/main/java/com/javaedge/concurrency/example/concurrent/CopyOnWriteArrayListExample.java b/src/main/java/com/javaedge/concurrency/concurrent/CopyOnWriteArrayListExample.java
similarity index 96%
rename from concurrency/src/main/java/com/javaedge/concurrency/example/concurrent/CopyOnWriteArrayListExample.java
rename to src/main/java/com/javaedge/concurrency/concurrent/CopyOnWriteArrayListExample.java
index a47d3d6..de26588 100755
--- a/concurrency/src/main/java/com/javaedge/concurrency/example/concurrent/CopyOnWriteArrayListExample.java
+++ b/src/main/java/com/javaedge/concurrency/concurrent/CopyOnWriteArrayListExample.java
@@ -1,4 +1,4 @@
-package com.javaedge.concurrency.example.concurrent;
+package main.java.com.javaedge.concurrency.concurrent;
import com.javaedge.concurrency.annoations.ThreadSafe;
import lombok.extern.slf4j.Slf4j;
diff --git a/concurrency/src/main/java/com/javaedge/concurrency/example/concurrent/CopyOnWriteArraySetExample.java b/src/main/java/com/javaedge/concurrency/concurrent/CopyOnWriteArraySetExample.java
similarity index 96%
rename from concurrency/src/main/java/com/javaedge/concurrency/example/concurrent/CopyOnWriteArraySetExample.java
rename to src/main/java/com/javaedge/concurrency/concurrent/CopyOnWriteArraySetExample.java
index 29d6aad..7d9c882 100755
--- a/concurrency/src/main/java/com/javaedge/concurrency/example/concurrent/CopyOnWriteArraySetExample.java
+++ b/src/main/java/com/javaedge/concurrency/concurrent/CopyOnWriteArraySetExample.java
@@ -1,4 +1,4 @@
-package com.javaedge.concurrency.example.concurrent;
+package main.java.com.javaedge.concurrency.concurrent;
import com.javaedge.concurrency.annoations.ThreadSafe;
import lombok.extern.slf4j.Slf4j;
diff --git a/src/main/java/com/javaedge/concurrency/condition/BlockedQueue.java b/src/main/java/com/javaedge/concurrency/condition/BlockedQueue.java
new file mode 100644
index 0000000..75936aa
--- /dev/null
+++ b/src/main/java/com/javaedge/concurrency/condition/BlockedQueue.java
@@ -0,0 +1,58 @@
+package main.java.com.javaedge.concurrency.condition;
+
+import java.util.concurrent.locks.Condition;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
+
+/**
+ * @author JavaEdge
+ * @date 2021/4/21
+ */
+public class BlockedQueue {
+
+ final Lock lock = new ReentrantLock();
+
+ /**
+ * 条件变量:队列不满
+ */
+ final Condition notFull = lock.newCondition();
+
+ /**
+ * 条件变量:队列不空
+ */
+ final Condition notEmpty = lock.newCondition();
+
+ void enq(T x) {
+ lock.lock();
+ try {
+// while (队列已满) {
+ while (x!=null) {
+ // 等待队列不满
+ notFull.await();
+ }
+ // 省略入队操作
+ // 入队后,通知可出队
+ notEmpty.signal();
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ } finally {
+ lock.unlock();
+ }
+ }
+
+ void deq() throws InterruptedException {
+ lock.lock();
+ try {
+// while (队列已空) {
+ while (true) {
+ // 等待队列不空
+ notEmpty.await();
+ }
+ // 省略出队操作
+ // 出队后,通知可入队
+// notFull.signal();
+ } finally {
+ lock.unlock();
+ }
+ }
+}
diff --git a/src/main/java/com/javaedge/concurrency/condition/DubboCondition.java b/src/main/java/com/javaedge/concurrency/condition/DubboCondition.java
new file mode 100644
index 0000000..17f492c
--- /dev/null
+++ b/src/main/java/com/javaedge/concurrency/condition/DubboCondition.java
@@ -0,0 +1,85 @@
+package main.java.com.javaedge.concurrency.condition;
+
+import redis.clients.jedis.Response;
+
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+import java.util.concurrent.locks.Condition;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
+
+/**
+ * @author JavaEdge
+ * @date 2021/4/21
+ */
+public class DubboCondition {
+
+ Response response;
+ /**
+ * 创建锁
+ */
+ private final Lock lock = new ReentrantLock();
+
+ /**
+ * 创建条件变量
+ */
+ private final Condition done = lock.newCondition();
+
+ /**
+ * 调用方通过该方法等待结果
+ *
+ * @param timeout
+ * @return
+ */
+ Object get(int timeout) throws TimeoutException {
+ long start = System.nanoTime();
+ // 获取锁
+ lock.lock();
+ try {
+ while (!isDone()) {
+ // 获取锁后,通过经典的在循环中调用await()方法来实现等待。
+ done.await(timeout, TimeUnit.SECONDS);
+ long cur = System.nanoTime();
+ if (isDone() ||
+ cur - start > timeout) {
+ break;
+ }
+ }
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ } finally {
+ // 释放锁
+ lock.unlock();
+ }
+ if (!isDone()) {
+ throw new TimeoutException();
+ }
+// return returnFromResponse();
+ return null;
+ }
+
+ /**
+ * RPC结果是否已经返回
+ *
+ * @return
+ */
+ boolean isDone() {
+ return response != null;
+ }
+
+ // RPC结果返回时调用该方法
+ private void doReceived(Response res) {
+ // 获取锁
+ lock.lock();
+ try {
+ response = res;
+ if (done != null) {
+ // 通知调用线程,结果已经返回,不用继续等待
+ done.signal();
+ }
+ } finally {
+ // 释放锁
+ lock.unlock();
+ }
+ }
+}
diff --git a/concurrency/src/main/java/com/javaedge/concurrency/example/count/CountExample1.java b/src/main/java/com/javaedge/concurrency/count/CountExample1.java
similarity index 91%
rename from concurrency/src/main/java/com/javaedge/concurrency/example/count/CountExample1.java
rename to src/main/java/com/javaedge/concurrency/count/CountExample1.java
index 7cfc0c1..d3f4817 100755
--- a/concurrency/src/main/java/com/javaedge/concurrency/example/count/CountExample1.java
+++ b/src/main/java/com/javaedge/concurrency/count/CountExample1.java
@@ -1,6 +1,6 @@
-package com.javaedge.concurrency.example.count;
+package main.java.com.javaedge.concurrency.count;
-import com.javaedge.concurrency.annoations.NotThreadSafe;
+import main.java.com.javaedge.concurrency.annoations.NotThreadSafe;
import lombok.extern.slf4j.Slf4j;
import java.util.concurrent.CountDownLatch;
diff --git a/concurrency/src/main/java/com/javaedge/concurrency/example/count/CountExample2.java b/src/main/java/com/javaedge/concurrency/count/CountExample2.java
similarity index 92%
rename from concurrency/src/main/java/com/javaedge/concurrency/example/count/CountExample2.java
rename to src/main/java/com/javaedge/concurrency/count/CountExample2.java
index a386b11..5499fa8 100755
--- a/concurrency/src/main/java/com/javaedge/concurrency/example/count/CountExample2.java
+++ b/src/main/java/com/javaedge/concurrency/count/CountExample2.java
@@ -1,6 +1,6 @@
-package com.javaedge.concurrency.example.count;
+package main.java.com.javaedge.concurrency.count;
-import com.javaedge.concurrency.annoations.ThreadSafe;
+import main.java.com.javaedge.concurrency.annoations.ThreadSafe;
import lombok.extern.slf4j.Slf4j;
import java.util.concurrent.CountDownLatch;
diff --git a/concurrency/src/main/java/com/javaedge/concurrency/example/count/CountExample3.java b/src/main/java/com/javaedge/concurrency/count/CountExample3.java
similarity index 91%
rename from concurrency/src/main/java/com/javaedge/concurrency/example/count/CountExample3.java
rename to src/main/java/com/javaedge/concurrency/count/CountExample3.java
index 5a63a03..402cbdb 100755
--- a/concurrency/src/main/java/com/javaedge/concurrency/example/count/CountExample3.java
+++ b/src/main/java/com/javaedge/concurrency/count/CountExample3.java
@@ -1,6 +1,6 @@
-package com.javaedge.concurrency.example.count;
+package main.java.com.javaedge.concurrency.count;
-import com.javaedge.concurrency.annoations.ThreadSafe;
+import main.java.com.javaedge.concurrency.annoations.ThreadSafe;
import lombok.extern.slf4j.Slf4j;
import java.util.concurrent.CountDownLatch;
diff --git a/concurrency/src/main/java/com/javaedge/concurrency/example/count/CountExample4.java b/src/main/java/com/javaedge/concurrency/count/CountExample4.java
similarity index 91%
rename from concurrency/src/main/java/com/javaedge/concurrency/example/count/CountExample4.java
rename to src/main/java/com/javaedge/concurrency/count/CountExample4.java
index 0d961f0..a3b87ae 100755
--- a/concurrency/src/main/java/com/javaedge/concurrency/example/count/CountExample4.java
+++ b/src/main/java/com/javaedge/concurrency/count/CountExample4.java
@@ -1,6 +1,6 @@
-package com.javaedge.concurrency.example.count;
+package main.java.com.javaedge.concurrency.count;
-import com.javaedge.concurrency.annoations.NotThreadSafe;
+import main.java.com.javaedge.concurrency.annoations.NotThreadSafe;
import lombok.extern.slf4j.Slf4j;
import java.util.concurrent.CountDownLatch;
diff --git a/concurrency/src/main/java/com/javaedge/concurrency/example/deadLock/DeadLock.java b/src/main/java/com/javaedge/concurrency/deadLock/DeadLock.java
similarity index 72%
rename from concurrency/src/main/java/com/javaedge/concurrency/example/deadLock/DeadLock.java
rename to src/main/java/com/javaedge/concurrency/deadLock/DeadLock.java
index 304ce17..0719f17 100755
--- a/concurrency/src/main/java/com/javaedge/concurrency/example/deadLock/DeadLock.java
+++ b/src/main/java/com/javaedge/concurrency/deadLock/DeadLock.java
@@ -1,4 +1,4 @@
-package com.javaedge.concurrency.example.deadLock;
+package main.java.com.javaedge.concurrency.deadLock;
import lombok.extern.slf4j.Slf4j;
@@ -9,37 +9,46 @@
* td1睡眠结束后需要锁定o2才能继续执行,而此时o2已被td2锁定;
* td2睡眠结束后需要锁定o1才能继续执行,而此时o1已被td1锁定;
* td1、td2相互等待,都需要得到对方锁定的资源才能继续执行,从而死锁。
+ *
+ * @author JavaEdge
*/
-
@Slf4j
public class DeadLock implements Runnable {
+
public int flag = 1;
- //静态对象是类的所有对象共享的
- private static Object o1 = new Object(), o2 = new Object();
+
+ /**
+ * 静态对象是类的所有对象共享的
+ */
+ private static final Object O_1 = new Object();
+ private static final Object O_2 = new Object();
@Override
public void run() {
+
log.info("flag:{}", flag);
+
if (flag == 1) {
- synchronized (o1) {
+ synchronized (O_1) {
try {
Thread.sleep(500);
} catch (Exception e) {
e.printStackTrace();
}
- synchronized (o2) {
+ synchronized (O_2) {
log.info("1");
}
}
}
+
if (flag == 0) {
- synchronized (o2) {
+ synchronized (O_2) {
try {
Thread.sleep(500);
} catch (Exception e) {
e.printStackTrace();
}
- synchronized (o1) {
+ synchronized (O_1) {
log.info("0");
}
}
@@ -51,8 +60,8 @@ public static void main(String[] args) {
DeadLock td2 = new DeadLock();
td1.flag = 1;
td2.flag = 0;
- //td1,td2都处于可执行状态,但JVM线程调度先执行哪个线程是不确定的。
- //td2的run()可能在td1的run()之前运行
+ // td1,td2都处于可执行状态,但JVM线程调度先执行哪个线程是不确定的
+ // td2的run()可能在td1的run()之前运行
new Thread(td1).start();
new Thread(td2).start();
}
diff --git a/concurrency/src/main/java/com/javaedge/concurrency/example/aqs/ForkJoinTaskExample.java b/src/main/java/com/javaedge/concurrency/forkjoin/ForkJoinTaskExample.java
similarity index 86%
rename from concurrency/src/main/java/com/javaedge/concurrency/example/aqs/ForkJoinTaskExample.java
rename to src/main/java/com/javaedge/concurrency/forkjoin/ForkJoinTaskExample.java
index 5380f90..58b2c59 100755
--- a/concurrency/src/main/java/com/javaedge/concurrency/example/aqs/ForkJoinTaskExample.java
+++ b/src/main/java/com/javaedge/concurrency/forkjoin/ForkJoinTaskExample.java
@@ -1,4 +1,4 @@
-package com.javaedge.concurrency.example.aqs;
+package main.java.com.javaedge.concurrency.forkjoin;
import lombok.extern.slf4j.Slf4j;
@@ -6,10 +6,13 @@
import java.util.concurrent.Future;
import java.util.concurrent.RecursiveTask;
+/**
+ * @author JavaEdge
+ */
@Slf4j
public class ForkJoinTaskExample extends RecursiveTask {
- public static final int threshold = 2;
+ public static final int THRESHOLD = 2;
private int start;
private int end;
@@ -23,7 +26,7 @@ protected Integer compute() {
int sum = 0;
//如果任务足够小就计算任务
- boolean canCompute = (end - start) <= threshold;
+ boolean canCompute = (end - start) <= THRESHOLD;
if (canCompute) {
for (int i = start; i <= end; i++) {
sum += i;
@@ -51,10 +54,10 @@ protected Integer compute() {
public static void main(String[] args) {
ForkJoinPool forkjoinPool = new ForkJoinPool();
- //生成一个计算任务,计算1+2+3+4
+ // 生成一个计算任务,计算1+2+3+4
ForkJoinTaskExample task = new ForkJoinTaskExample(1, 100);
- //执行一个任务
+ // 执行一个任务
Future result = forkjoinPool.submit(task);
try {
diff --git a/src/main/java/com/javaedge/concurrency/forkjoin/ForkJoinTaskExample2.java b/src/main/java/com/javaedge/concurrency/forkjoin/ForkJoinTaskExample2.java
new file mode 100755
index 0000000..4621040
--- /dev/null
+++ b/src/main/java/com/javaedge/concurrency/forkjoin/ForkJoinTaskExample2.java
@@ -0,0 +1,52 @@
+package main.java.com.javaedge.concurrency.forkjoin;
+
+import lombok.extern.slf4j.Slf4j;
+
+import java.util.concurrent.ForkJoinPool;
+import java.util.concurrent.RecursiveTask;
+
+/**
+ * @author JavaEdge
+ */
+@Slf4j
+public class ForkJoinTaskExample2 {
+ public static void main(String[] args) {
+ // 创建分治任务线程池
+ ForkJoinPool forkJoinPool = new ForkJoinPool(4);
+
+ // 创建分治任务
+ Fibonacci fib = new Fibonacci(30);
+
+ // 启动分治任务
+ Integer result = forkJoinPool.invoke(fib);
+
+ System.out.println(result);
+ }
+
+ /**
+ * 数列的递归任务 需要有返回值
+ */
+ static class Fibonacci extends RecursiveTask {
+ final int n;
+
+ Fibonacci(int n) {
+ this.n = n;
+ }
+
+ @Override
+ protected Integer compute() {
+ if (n <= 1) {
+ return n;
+ }
+
+ Fibonacci f1 = new Fibonacci(n - 1);
+
+ // 创建子任务
+ f1.fork();
+ Fibonacci f2 = new Fibonacci(n - 2);
+
+ // 等待子任务结果,并合并结果
+ return f2.compute() + f1.join();
+ }
+ }
+}
diff --git a/src/main/java/com/javaedge/concurrency/forkjoin/ForkJoinTaskExample3.java b/src/main/java/com/javaedge/concurrency/forkjoin/ForkJoinTaskExample3.java
new file mode 100755
index 0000000..a33e195
--- /dev/null
+++ b/src/main/java/com/javaedge/concurrency/forkjoin/ForkJoinTaskExample3.java
@@ -0,0 +1,193 @@
+package main.java.com.javaedge.concurrency.forkjoin;
+
+import lombok.extern.slf4j.Slf4j;
+import org.junit.Test;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.ForkJoinPool;
+import java.util.concurrent.RecursiveTask;
+
+/**
+ * @author JavaEdge
+ */
+@Slf4j
+public class ForkJoinTaskExample3 {
+
+ public static void main(String[] args) {
+ String[] fc = {"hello world",
+ "hello me",
+ "hello fork",
+ "hello join",
+ "fork join in world"};
+ //创建ForkJoin线程池
+ ForkJoinPool fjp = new ForkJoinPool(3);
+ //创建任务
+ MR mr = new MR(fc, 0, fc.length);
+ //启动任务
+ Map result = fjp.invoke(mr);
+ //输出结果
+ result.forEach((k, v) -> System.out.println(k + ":" + v));
+ }
+
+ /**
+ * MR模拟类
+ */
+ static class MR extends RecursiveTask