diff --git a/02nio/nio01/pom.xml b/02nio/nio01/pom.xml
index e42a62f2..8ba80b9b 100644
--- a/02nio/nio01/pom.xml
+++ b/02nio/nio01/pom.xml
@@ -59,6 +59,11 @@
netty-all
4.1.51.Final
+
+ com.squareup.okhttp3
+ okhttp
+ 4.9.0
+
diff --git a/03concurrency/0301/pom.xml b/03concurrency/0301/pom.xml
index 55691a2d..3a8878fb 100644
--- a/03concurrency/0301/pom.xml
+++ b/03concurrency/0301/pom.xml
@@ -19,6 +19,14 @@
+
+
+ junit
+ junit
+ 4.11
+ compile
+
+
\ No newline at end of file
diff --git a/03concurrency/0301/src/main/java/java0/conc0301/DaemonThread.java b/03concurrency/0301/src/main/java/java0/conc0301/DaemonThread.java
index 5fec537e..5be8f3ef 100644
--- a/03concurrency/0301/src/main/java/java0/conc0301/DaemonThread.java
+++ b/03concurrency/0301/src/main/java/java0/conc0301/DaemonThread.java
@@ -1,5 +1,10 @@
package java0.conc0301;
+/**
+ * 总结:
+ * JAVA 进程中,如果运行的线程都是 daemon 线程,则进程可以正常结束,
+ * 如果运行的线程中有非 daemon 线程,则进程需要等待所有的非daemon线程都运行完毕,才能正常结束。
+ */
public class DaemonThread {
public static void main(String[] args) throws InterruptedException {
diff --git a/03concurrency/0301/src/main/java/java0/conc0301/Runner2.java b/03concurrency/0301/src/main/java/java0/conc0301/Runner2.java
index d80e8c14..d91aa0fd 100644
--- a/03concurrency/0301/src/main/java/java0/conc0301/Runner2.java
+++ b/03concurrency/0301/src/main/java/java0/conc0301/Runner2.java
@@ -1,5 +1,9 @@
package java0.conc0301;
+/**
+ * Thread.isInterrupted() 不会重置 Interrupted 状态
+ * Thread.interrupted() 重置 Interrupted 状态
+ */
public class Runner2 implements Runnable {
@Override
diff --git a/03concurrency/0301/src/main/java/java0/conc0301/ThreadCount.java b/03concurrency/0301/src/main/java/java0/conc0301/ThreadCount.java
index 8e13af9e..2898a07d 100644
--- a/03concurrency/0301/src/main/java/java0/conc0301/ThreadCount.java
+++ b/03concurrency/0301/src/main/java/java0/conc0301/ThreadCount.java
@@ -1,5 +1,17 @@
package java0.conc0301;
+/**
+ * 线程信息:
+ * 在没有业务线程情况下,总共有两个线程组,6个线程(4个系统组的线程,2个主线程组的线程),如下所示:
+ * java.lang.ThreadGroup[name=system,maxpri=10]
+ * Thread[Reference Handler,10,system]
+ * Thread[Finalizer,8,system]
+ * Thread[Signal Dispatcher,9,system]
+ * Thread[Attach Listener,5,system]
+ * java.lang.ThreadGroup[name=main,maxpri=10]
+ * Thread[main,5,main]
+ * Thread[Monitor Ctrl-Break,5,main]
+ */
public class ThreadCount {
public static void main(String[] args) throws InterruptedException {
//System.out.println("system:"+Thread.currentThread().getThreadGroup().getParent());
diff --git a/03concurrency/0301/src/main/java/java0/conc0301/ThreadMain2.java b/03concurrency/0301/src/main/java/java0/conc0301/ThreadMain2.java
index b365b40c..a1880779 100644
--- a/03concurrency/0301/src/main/java/java0/conc0301/ThreadMain2.java
+++ b/03concurrency/0301/src/main/java/java0/conc0301/ThreadMain2.java
@@ -9,12 +9,16 @@ public static void main(String[] args) {
new Thread(threadB, "线程名称:(" + i + ")").start();
}
+ Thread.currentThread().getThreadGroup().list();
+
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
+ System.out.println("线程组成员:");
+
//返回对当前正在执行的线程对象的引用
Thread threadMain = Thread.currentThread();
System.out.println("这是主线程:");
diff --git a/03concurrency/0301/src/main/java/java0/conc0301/op/Join.java b/03concurrency/0301/src/main/java/java0/conc0301/op/Join.java
index 1cbf6a5a..bf976071 100644
--- a/03concurrency/0301/src/main/java/java0/conc0301/op/Join.java
+++ b/03concurrency/0301/src/main/java/java0/conc0301/op/Join.java
@@ -1,12 +1,21 @@
package java0.conc0301.op;
+/**
+ * 总结:线程A结束的时候,JVM内部会发送通知 notifyAll 给该线程对象A上的等待线程,唤醒在线程对象A上等待的线程
+ * 其中this 代表线程的执行的task对象。
+ * JAVA线程可以看作由两部分组成,
+ * 1. Java Task 对象,由JVM回调执行线程中的任务,即run方法的对象实体。
+ * 2. 操作系统的线程,一个Java 线程会一对一一个操作系统线程,
+ * 而Thread 中的 this对象代表Java Task 对象实体,
+ * Thread.current()返回的线程代表的是操作系统线程
+ */
public class Join {
public static void main(String[] args) {
Object oo = new Object();
MyThread thread1 = new MyThread("thread1 -- ");
- //oo = thread1;
+ oo = thread1;
thread1.setOo(oo);
thread1.start();
@@ -42,10 +51,12 @@ public MyThread(String name) {
@Override
public void run() {
- synchronized (oo) { // 这里用oo或this,效果不同
+ synchronized (this) { // 这里用oo或this,效果不同
for (int i = 0; i < 100; i++) {
System.out.println(name + i);
}
+ //my Test: add notifyAll to solve dead lock
+ //oo.notifyAll();
}
}
diff --git a/03concurrency/0301/src/main/java/java0/conc0301/op/WaitAndNotify.java b/03concurrency/0301/src/main/java/java0/conc0301/op/WaitAndNotify.java
index e3956c10..e0059237 100644
--- a/03concurrency/0301/src/main/java/java0/conc0301/op/WaitAndNotify.java
+++ b/03concurrency/0301/src/main/java/java0/conc0301/op/WaitAndNotify.java
@@ -37,7 +37,10 @@ public static void main(String[] args) {
class MethodClass {
// 定义生产最大量
private final int MAX_COUNT = 20;
-
+
+ /**
+ * 单线程创建 product, 不需要加锁
+ */
int productCount = 0;
public synchronized void product() throws InterruptedException {
diff --git a/03concurrency/0301/src/main/java/java0/conc0301/sync/Counter.java b/03concurrency/0301/src/main/java/java0/conc0301/sync/Counter.java
index 68d869f6..b5e47132 100644
--- a/03concurrency/0301/src/main/java/java0/conc0301/sync/Counter.java
+++ b/03concurrency/0301/src/main/java/java0/conc0301/sync/Counter.java
@@ -1,5 +1,8 @@
package java0.conc0301.sync;
+/**
+ * volatile 只能保证有序性和可见性,不能保证原子性
+ */
public class Counter {
public final static int A=10;
diff --git a/03concurrency/0301/src/main/java/java0/conc0301/sync/Thread1.java b/03concurrency/0301/src/main/java/java0/conc0301/sync/Thread1.java
index 4dc7513f..6f5cb550 100644
--- a/03concurrency/0301/src/main/java/java0/conc0301/sync/Thread1.java
+++ b/03concurrency/0301/src/main/java/java0/conc0301/sync/Thread1.java
@@ -1,11 +1,19 @@
package java0.conc0301.sync;
+
+/**
+ * Thread 线程对象中的任意方法获取的 this 代表线程对象本身,并不代表线程信息(线程信息中包括操作系统线程)
+ * Thread.currentThread() 代表操作系统对应的线程信息.
+ * 所以 this != Thread.currentThread() ,this 代表 Task 对象信息
+ * 如下所示:TA 线程和 TB线程在操作系统上创建了两个操作系统线程对应 A线程 和 B线程,但是它们公用一个Task 对象信息, this是 task 对象信息
+ */
public class Thread1 implements Runnable {
@Override
public void run() {
synchronized (this) {
+ System.out.println(this);
for (int i = 0; i < 10; i++) {
System.out.println(Thread.currentThread().getName() + " synchronized loop " + i);
}
@@ -14,8 +22,10 @@ public void run() {
public static void main(String[] args) {
Thread1 t1 = new Thread1();
+ System.out.println("the Thread1 obj t1:" + t1);
Thread ta = new Thread(t1, "A");
Thread tb = new Thread(t1, "B");
+
ta.start();
tb.start();
}
diff --git a/03concurrency/0301/src/main/java/java0/conc0301/sync/Thread2.java b/03concurrency/0301/src/main/java/java0/conc0301/sync/Thread2.java
index d0f0638b..741ee3cd 100644
--- a/03concurrency/0301/src/main/java/java0/conc0301/sync/Thread2.java
+++ b/03concurrency/0301/src/main/java/java0/conc0301/sync/Thread2.java
@@ -1,6 +1,10 @@
package java0.conc0301.sync;
+/**
+ * 总结:
+ * 两个Java Thread 对应两个操作系统线程,同时同享一个java task 对象实例
+ */
public class Thread2 {
public void m4t1() {
diff --git a/03concurrency/0301/src/main/java/java0/conc0301/sync/Thread3.java b/03concurrency/0301/src/main/java/java0/conc0301/sync/Thread3.java
index f9d5d742..4c3cef9f 100644
--- a/03concurrency/0301/src/main/java/java0/conc0301/sync/Thread3.java
+++ b/03concurrency/0301/src/main/java/java0/conc0301/sync/Thread3.java
@@ -14,7 +14,7 @@ private void m4t1() {
}
}
- private void m4t2() {
+ private synchronized void m4t2() {
int i = 5;
while (i-- > 0) {
System.out.println(Thread.currentThread().getName() + " : Inner.m4t2()=" + i);
diff --git a/03concurrency/0301/src/main/java/java0/conc0302/atomic/AtomicCount.java b/03concurrency/0301/src/main/java/java0/conc0302/atomic/AtomicCount.java
index cece1ec3..85270bb6 100644
--- a/03concurrency/0301/src/main/java/java0/conc0302/atomic/AtomicCount.java
+++ b/03concurrency/0301/src/main/java/java0/conc0302/atomic/AtomicCount.java
@@ -3,7 +3,7 @@
import java.util.concurrent.atomic.AtomicInteger;
-public class AtomicCount {
+public class AtomicCount implements CountInf {
private AtomicInteger num = new AtomicInteger();
diff --git a/03concurrency/0301/src/main/java/java0/conc0302/atomic/AtomicMain.java b/03concurrency/0301/src/main/java/java0/conc0302/atomic/AtomicMain.java
index 297eb343..5700aedf 100644
--- a/03concurrency/0301/src/main/java/java0/conc0302/atomic/AtomicMain.java
+++ b/03concurrency/0301/src/main/java/java0/conc0302/atomic/AtomicMain.java
@@ -1,16 +1,23 @@
package java0.conc0302.atomic;
+/**
+ * SyncCount 使用公平锁处理共享资源,
+ * 由于公平锁效率较低,所有5s内没有完成计算,就返回总和,所以结果错误.
+ * 同样时间非公平锁5s内可以完成计算,结果正确。
+ * 时间增加到10s后结果正确。
+ *
+ */
public class AtomicMain {
public static void main(String[] args) {
- final SyncCount count = new SyncCount();
+ final CountInf count = new SyncCount();
for (int i = 0; i < 100; i++) {
new Thread(new Runnable() {
@Override
public void run() {
for (int j = 0; j < 10000; j++) {
- count.add();
+ count.add();
}
}
}).start();
diff --git a/03concurrency/0301/src/main/java/java0/conc0302/atomic/Count.java b/03concurrency/0301/src/main/java/java0/conc0302/atomic/Count.java
index 02fd13d5..9c648002 100644
--- a/03concurrency/0301/src/main/java/java0/conc0302/atomic/Count.java
+++ b/03concurrency/0301/src/main/java/java0/conc0302/atomic/Count.java
@@ -1,7 +1,7 @@
package java0.conc0302.atomic;
-public class Count {
+public class Count implements CountInf{
private int num = 0;
diff --git a/03concurrency/0301/src/main/java/java0/conc0302/atomic/LongDemo.java b/03concurrency/0301/src/main/java/java0/conc0302/atomic/LongDemo.java
index 6a7356c6..3a5fedaa 100644
--- a/03concurrency/0301/src/main/java/java0/conc0302/atomic/LongDemo.java
+++ b/03concurrency/0301/src/main/java/java0/conc0302/atomic/LongDemo.java
@@ -3,6 +3,9 @@
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.atomic.LongAdder;
+/**
+ *
+ */
public class LongDemo {
public static void main(String[] args) {
diff --git a/03concurrency/0301/src/main/java/java0/conc0302/atomic/SyncCount.java b/03concurrency/0301/src/main/java/java0/conc0302/atomic/SyncCount.java
index b95c7cff..d1d206fe 100644
--- a/03concurrency/0301/src/main/java/java0/conc0302/atomic/SyncCount.java
+++ b/03concurrency/0301/src/main/java/java0/conc0302/atomic/SyncCount.java
@@ -4,7 +4,13 @@
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
-public class SyncCount {
+/**
+ * 总结:公平锁不能保证原子性
+ * 非公平锁可以保证原子性,
+ * 为什么??
+ *
+ */
+public class SyncCount implements CountInf {
private int num = 0;
diff --git a/03concurrency/0301/src/main/java/java0/conc0302/lock/ConditionDemo.java b/03concurrency/0301/src/main/java/java0/conc0302/lock/ConditionDemo.java
index 33ad0bab..0155cd7f 100644
--- a/03concurrency/0301/src/main/java/java0/conc0302/lock/ConditionDemo.java
+++ b/03concurrency/0301/src/main/java/java0/conc0302/lock/ConditionDemo.java
@@ -42,4 +42,39 @@ public Object take() throws InterruptedException {
lock.unlock();
}
}
+
+ public static void main(String[] args){
+ ConditionDemo test = new ConditionDemo();
+
+ Thread putThread = new Thread(new Runnable() {
+ @Override
+ public void run() {
+ for(int i=0;i<1000;i++){
+ try {
+ test.put(i);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+ });
+ putThread.setName("putThread");
+ putThread.start();
+
+ Thread takeThread = new Thread(new Runnable() {
+ @Override
+ public void run() {
+ for(int i=0;i<1000;i++){
+ try {
+ test.take();
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+ });
+ takeThread.setName("takeThread");
+ takeThread.start();
+
+ }
}
\ No newline at end of file
diff --git a/03concurrency/0301/src/main/java/java0/conc0302/lock/Count3.java b/03concurrency/0301/src/main/java/java0/conc0302/lock/Count3.java
index f99eaa3e..01c94759 100644
--- a/03concurrency/0301/src/main/java/java0/conc0302/lock/Count3.java
+++ b/03concurrency/0301/src/main/java/java0/conc0302/lock/Count3.java
@@ -1,6 +1,14 @@
package java0.conc0302.lock;
+/**
+ * 总结:
+ * 死锁场景:
+ * 获取多把锁的顺序和释放多把锁的顺序不一致,导致死锁
+ * 产生死锁的必要条件:
+ * 1. 已经获取锁,尝试获取其他锁
+ * 2. 获取锁过程中不可中断或超时
+ */
public class Count3 {
private byte[] lock1 = new byte[1];
diff --git a/03concurrency/0301/src/main/java/java0/conc0302/lock/LockSupportDemo.java b/03concurrency/0301/src/main/java/java0/conc0302/lock/LockSupportDemo.java
index 18f598f1..066e8fee 100644
--- a/03concurrency/0301/src/main/java/java0/conc0302/lock/LockSupportDemo.java
+++ b/03concurrency/0301/src/main/java/java0/conc0302/lock/LockSupportDemo.java
@@ -2,6 +2,15 @@
import java.util.concurrent.locks.LockSupport;
+/**
+ * 总结:LockSupport.park(t1) 休眠本线程t1后,并不释放锁信息,或者可以理解为与锁信息无关,
+ * LockSupport.park(t1) 仅仅是休眠线程t1。
+ *
+ * 唤醒被LockSupport.park()的线程,可以在其他线程中通过两种方式唤醒:
+ * 1. LockSupport.unpark(t1);
+ * 2. t1.interrupt()
+ *
+ */
public class LockSupportDemo {
public static Object u = new Object();
diff --git a/03concurrency/0301/src/main/java/java0/conc0302/lock/ReentrantReadWriteLockDemo2.java b/03concurrency/0301/src/main/java/java0/conc0302/lock/ReentrantReadWriteLockDemo2.java
index 82b4001b..e18e26ba 100644
--- a/03concurrency/0301/src/main/java/java0/conc0302/lock/ReentrantReadWriteLockDemo2.java
+++ b/03concurrency/0301/src/main/java/java0/conc0302/lock/ReentrantReadWriteLockDemo2.java
@@ -19,6 +19,7 @@ public Object readWrite(String key) {
value = map.get(key);
if (value == null) {
System.out.println("2.数据不存在,则释放读锁,开启写锁");
+ // 锁升级
rwLock.readLock().unlock();
rwLock.writeLock().lock();
try {
diff --git a/03concurrency/0301/src/main/java/java0/conc0302/lock/ReentrantReadWriteLockDemo3.java b/03concurrency/0301/src/main/java/java0/conc0302/lock/ReentrantReadWriteLockDemo3.java
new file mode 100644
index 00000000..9cd34b11
--- /dev/null
+++ b/03concurrency/0301/src/main/java/java0/conc0302/lock/ReentrantReadWriteLockDemo3.java
@@ -0,0 +1,50 @@
+package java0.conc0302.lock;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
+
+public class ReentrantReadWriteLockDemo3 {
+ private final Map map = new HashMap<>();
+
+ private final ReentrantReadWriteLock rwLock = new ReentrantReadWriteLock();
+
+ public Object readWrite(String key) {
+ Object value = null;
+ System.out.println("1.首先开启读锁去缓存中取数据");
+ rwLock.readLock().lock();
+ try {
+ value = map.get(key);
+ if (value == null) {
+ System.out.println("2.数据不存在,则释放读锁,开启写锁");
+ // 锁升级
+ rwLock.readLock().unlock();
+ rwLock.writeLock().lock();
+ try {
+ if (value == null) {
+ value = "aaaa";
+ }
+ /**
+ * 锁降级,可以使本线程一直占有锁,
+ * 如果不使用锁降级,需要释放写锁,再重新获取读锁,在这个过程中可能长时间无法获取读锁
+ * 锁降级则可以直接获取读锁,防止其他线程竞争读资源
+ */
+ System.out.println("3.设置数据成功,写锁降级降为读锁");
+ rwLock.readLock().lock();
+ } finally {
+ System.out.println("4.释放写锁");
+ rwLock.writeLock().unlock();
+ }
+ }
+ } finally {
+ System.out.println("5.释放读锁");
+ rwLock.readLock().unlock();
+ }
+ return value;
+ }
+
+ public static void main(String[] args) {
+ ReentrantReadWriteLockDemo3 demo3 = new ReentrantReadWriteLockDemo3();
+ demo3.readWrite("bingfabiancheng");
+ }
+}
diff --git a/03concurrency/0301/src/main/java/java0/conc0302/lock/TestFair.java b/03concurrency/0301/src/main/java/java0/conc0302/lock/TestFair.java
index 1dc47538..d230c964 100644
--- a/03concurrency/0301/src/main/java/java0/conc0302/lock/TestFair.java
+++ b/03concurrency/0301/src/main/java/java0/conc0302/lock/TestFair.java
@@ -3,6 +3,10 @@
import java.util.concurrent.atomic.AtomicReference;
import java.util.concurrent.locks.ReentrantLock;
+/**
+ * 总结:非公平锁是公平锁效率的100多倍
+ * 等待所有累加线程都结束,可以通过记录尾启动业务线程前的线程总数。
+ */
public class TestFair {
public static volatile int race=0;
public static ReentrantLock lock = new ReentrantLock(true); // 改成false会好100倍
@@ -16,7 +20,7 @@ public static void main(String[]args){
int count = Thread.activeCount();
long now = System.currentTimeMillis();
System.out.println(count);
- AtomicReference sign =new AtomicReference<>();
+ //AtomicReference sign =new AtomicReference<>();
Thread[]threads=new Thread[THREADS_COUNT]; //定义20个线程
for(int i=0;i list = new ArrayList();
// List list = new LinkedList<>();
- List list = new Vector<>();
+ // List list = new Vector<>();
// 只有CopyOnWriteArrayList 安全,不报错
- //List list = new CopyOnWriteArrayList();
+ List list = new CopyOnWriteArrayList();
for (int i = 0; i < 10000; i++)
{
diff --git a/03concurrency/0301/src/main/java/java0/conc0303/collection/CopyOnWriteArrayListDemo1.java b/03concurrency/0301/src/main/java/java0/conc0303/collection/CopyOnWriteArrayListDemo1.java
index 82718cdb..ab2ca0f4 100644
--- a/03concurrency/0301/src/main/java/java0/conc0303/collection/CopyOnWriteArrayListDemo1.java
+++ b/03concurrency/0301/src/main/java/java0/conc0303/collection/CopyOnWriteArrayListDemo1.java
@@ -6,11 +6,13 @@
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
-
+/**
+ *
+ */
public class CopyOnWriteArrayListDemo1 {
private static final int THREAD_POOL_MAX_NUM = 10;
- private List mList = new ArrayList(); // ArrayList 无法运行
- //private List mList = new CopyOnWriteArrayList<>();
+ //private List mList = new ArrayList(); // ArrayList 无法运行
+ private List mList = new CopyOnWriteArrayList<>();
public static void main(String args[]) {
new CopyOnWriteArrayListDemo1().start();
@@ -43,7 +45,7 @@ public ListReader(List list) {
public void run() {
if (this.mList != null) {
for (String str : this.mList) {
- System.out.println(Thread.currentThread().getName() + " : " + str);
+ System.out.println(Thread.currentThread().getName() + " read data: " + str);
}
}
}
@@ -62,6 +64,7 @@ public ListWriter(List list, int index) {
public void run() {
if (this.mList != null) {
//this.mList.remove(this.mIndex);
+ System.out.println(Thread.currentThread().getName() + " write data:"+mIndex);
this.mList.add("...... add " + mIndex + " ......");
}
}
diff --git a/03concurrency/0301/src/main/java/java0/conc0303/future/FutureDemo1.java b/03concurrency/0301/src/main/java/java0/conc0303/future/FutureDemo1.java
index 14a16383..d3ce629f 100644
--- a/03concurrency/0301/src/main/java/java0/conc0303/future/FutureDemo1.java
+++ b/03concurrency/0301/src/main/java/java0/conc0303/future/FutureDemo1.java
@@ -8,6 +8,7 @@ public static void main(String[] args) {
ExecutorService executor = Executors.newCachedThreadPool();
Future result = executor.submit(new Callable() {
public Integer call() throws Exception {
+ Thread.sleep(1000);
return new Random().nextInt();
}
});
diff --git a/03concurrency/0301/src/main/java/java0/conc0303/future/FutureTask1.java b/03concurrency/0301/src/main/java/java0/conc0303/future/FutureTask1.java
index 69499819..4783c9ee 100644
--- a/03concurrency/0301/src/main/java/java0/conc0303/future/FutureTask1.java
+++ b/03concurrency/0301/src/main/java/java0/conc0303/future/FutureTask1.java
@@ -6,7 +6,7 @@
public class FutureTask1 {
public static void main(String[] args) {
//第一种方式
- FutureTask task = new FutureTask(new Callable() {
+ FutureTask task = new FutureTask<>(new Callable() {
@Override
public Integer call() throws Exception {
return new Random().nextInt();
diff --git a/03concurrency/0301/src/main/java/java0/conc0303/homework/AsyncResult.java b/03concurrency/0301/src/main/java/java0/conc0303/homework/AsyncResult.java
new file mode 100644
index 00000000..2e402e11
--- /dev/null
+++ b/03concurrency/0301/src/main/java/java0/conc0303/homework/AsyncResult.java
@@ -0,0 +1,16 @@
+package java0.conc0303.homework;
+
+public interface AsyncResult {
+
+ int getResult() throws Exception;
+
+ default int sum() {
+ return fibo(36);
+ }
+
+ default int fibo(int a) {
+ if ( a < 2)
+ return 1;
+ return fibo(a-1) + fibo(a-2);
+ }
+}
diff --git a/03concurrency/0301/src/main/java/java0/conc0303/homework/AsyncResultImpl1.java b/03concurrency/0301/src/main/java/java0/conc0303/homework/AsyncResultImpl1.java
new file mode 100644
index 00000000..1ae62f30
--- /dev/null
+++ b/03concurrency/0301/src/main/java/java0/conc0303/homework/AsyncResultImpl1.java
@@ -0,0 +1,24 @@
+package java0.conc0303.homework;
+
+/**
+ * 应用 volatile 机制
+ */
+public class AsyncResultImpl1 implements AsyncResult {
+ private volatile int result = -1;
+ private volatile boolean hadComputed = false;
+ @Override
+ public int getResult() throws Exception {
+ new Thread(new Runnable() {
+ @Override
+ public void run() {
+ result = sum();
+ hadComputed = true;
+ }
+ }).start();
+
+ while (!hadComputed){
+ Thread.yield();// 防止main线程一直占用CPU资源
+ }
+ return result;
+ }
+}
diff --git a/03concurrency/0301/src/main/java/java0/conc0303/homework/AsyncResultImpl10.java b/03concurrency/0301/src/main/java/java0/conc0303/homework/AsyncResultImpl10.java
new file mode 100644
index 00000000..6607fdc2
--- /dev/null
+++ b/03concurrency/0301/src/main/java/java0/conc0303/homework/AsyncResultImpl10.java
@@ -0,0 +1,22 @@
+package java0.conc0303.homework;
+
+import java.util.concurrent.ArrayBlockingQueue;
+import java.util.concurrent.BlockingQueue;
+
+/**
+ * 应用阻塞队列
+ */
+public class AsyncResultImpl10 implements AsyncResult {
+ private BlockingQueue blockingQueue = new ArrayBlockingQueue<>(1);
+ @Override
+ public int getResult() throws Exception {
+ new Thread(new Runnable() {
+ @Override
+ public void run() {
+ blockingQueue.offer(sum());
+ }
+ }).start();
+
+ return blockingQueue.take();
+ }
+}
diff --git a/03concurrency/0301/src/main/java/java0/conc0303/homework/AsyncResultImpl2.java b/03concurrency/0301/src/main/java/java0/conc0303/homework/AsyncResultImpl2.java
new file mode 100644
index 00000000..0d321b2b
--- /dev/null
+++ b/03concurrency/0301/src/main/java/java0/conc0303/homework/AsyncResultImpl2.java
@@ -0,0 +1,29 @@
+package java0.conc0303.homework;
+
+import java.util.concurrent.atomic.AtomicInteger;
+
+/**
+ * 应用CAS机制
+ */
+public class AsyncResultImpl2 implements AsyncResult {
+
+ private volatile int result = -1;
+
+ private AtomicInteger tag = new AtomicInteger(1);
+
+ @Override
+ public int getResult() throws Exception {
+ new Thread(new Runnable() {
+ @Override
+ public void run() {
+ result = sum();
+ tag.getAndDecrement();
+ }
+ }).start();
+
+ while (tag.get() > 0){
+ Thread.yield();
+ }
+ return result;
+ }
+}
diff --git a/03concurrency/0301/src/main/java/java0/conc0303/homework/AsyncResultImpl3.java b/03concurrency/0301/src/main/java/java0/conc0303/homework/AsyncResultImpl3.java
new file mode 100644
index 00000000..664b84ff
--- /dev/null
+++ b/03concurrency/0301/src/main/java/java0/conc0303/homework/AsyncResultImpl3.java
@@ -0,0 +1,21 @@
+package java0.conc0303.homework;
+
+/**
+ * 应用join 机制
+ */
+public class AsyncResultImpl3 implements AsyncResult {
+ private volatile int result = -1;
+ @Override
+ public int getResult() throws Exception {
+ Thread t1 = new Thread(new Runnable() {
+ @Override
+ public void run() {
+ result = sum();
+ }
+ });
+ t1.start();
+ t1.join();
+
+ return result;
+ }
+}
diff --git a/03concurrency/0301/src/main/java/java0/conc0303/homework/AsyncResultImpl4.java b/03concurrency/0301/src/main/java/java0/conc0303/homework/AsyncResultImpl4.java
new file mode 100644
index 00000000..7a0991b8
--- /dev/null
+++ b/03concurrency/0301/src/main/java/java0/conc0303/homework/AsyncResultImpl4.java
@@ -0,0 +1,27 @@
+package java0.conc0303.homework;
+
+/**
+ * 应用传统的synchronized锁通知机制
+ */
+public class AsyncResultImpl4 implements AsyncResult {
+ private volatile int result = -1;
+ private final Object getResultLock = new Object();
+
+ @Override
+ public int getResult() throws Exception {
+ new Thread(new Runnable() {
+ @Override
+ public void run() {
+ synchronized (getResultLock) {
+ result = sum();
+ getResultLock.notifyAll();
+ }
+ }
+ }).start();
+
+ synchronized (getResultLock) {
+ getResultLock.wait();
+ return result;
+ }
+ }
+}
diff --git a/03concurrency/0301/src/main/java/java0/conc0303/homework/AsyncResultImpl5.java b/03concurrency/0301/src/main/java/java0/conc0303/homework/AsyncResultImpl5.java
new file mode 100644
index 00000000..17f7a78b
--- /dev/null
+++ b/03concurrency/0301/src/main/java/java0/conc0303/homework/AsyncResultImpl5.java
@@ -0,0 +1,34 @@
+package java0.conc0303.homework;
+
+import java.util.concurrent.locks.Condition;
+import java.util.concurrent.locks.ReentrantLock;
+
+public class AsyncResultImpl5 implements AsyncResult {
+ private volatile int result = -1;
+
+ @Override
+ public int getResult() throws Exception {
+ final ReentrantLock lock = new ReentrantLock(false);
+ Condition hadCompute = lock.newCondition();
+ new Thread(new Runnable() {
+ @Override
+ public void run() {
+ lock.lock();
+ try {
+ result = sum();
+ hadCompute.signalAll();
+ }finally {
+ lock.unlock();
+ }
+ }
+ }).start();
+
+ lock.lock();
+ try {
+ hadCompute.await();
+ return result;
+ }finally {
+ lock.unlock();
+ }
+ }
+}
diff --git a/03concurrency/0301/src/main/java/java0/conc0303/homework/AsyncResultImpl6.java b/03concurrency/0301/src/main/java/java0/conc0303/homework/AsyncResultImpl6.java
new file mode 100644
index 00000000..96080ce8
--- /dev/null
+++ b/03concurrency/0301/src/main/java/java0/conc0303/homework/AsyncResultImpl6.java
@@ -0,0 +1,23 @@
+package java0.conc0303.homework;
+
+import java.util.concurrent.CountDownLatch;
+
+/**
+ * 应用CountDownLatch机制
+ */
+public class AsyncResultImpl6 implements AsyncResult{
+ private volatile int result = -1;
+ @Override
+ public int getResult() throws Exception {
+ CountDownLatch countDownLatch = new CountDownLatch(1);
+ new Thread(new Runnable() {
+ @Override
+ public void run() {
+ result = sum();
+ countDownLatch.countDown();
+ }
+ }).start();
+ countDownLatch.await();
+ return result;
+ }
+}
diff --git a/03concurrency/0301/src/main/java/java0/conc0303/homework/AsyncResultImpl7.java b/03concurrency/0301/src/main/java/java0/conc0303/homework/AsyncResultImpl7.java
new file mode 100644
index 00000000..14cc4152
--- /dev/null
+++ b/03concurrency/0301/src/main/java/java0/conc0303/homework/AsyncResultImpl7.java
@@ -0,0 +1,27 @@
+package java0.conc0303.homework;
+
+import java.util.concurrent.CyclicBarrier;
+
+/**
+ * 应用 CyclicBarrier 机制
+ */
+public class AsyncResultImpl7 implements AsyncResult {
+ private volatile int result = -1;
+ @Override
+ public int getResult() throws Exception {
+ final CyclicBarrier cyclicBarrier = new CyclicBarrier(2);
+ new Thread(new Runnable() {
+ @Override
+ public void run() {
+ try {
+ result = sum();
+ cyclicBarrier.await();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+ }).start();
+ cyclicBarrier.await();
+ return result;
+ }
+}
diff --git a/03concurrency/0301/src/main/java/java0/conc0303/homework/AsyncResultImpl8.java b/03concurrency/0301/src/main/java/java0/conc0303/homework/AsyncResultImpl8.java
new file mode 100644
index 00000000..c69d4c7d
--- /dev/null
+++ b/03concurrency/0301/src/main/java/java0/conc0303/homework/AsyncResultImpl8.java
@@ -0,0 +1,29 @@
+package java0.conc0303.homework;
+
+import java.util.concurrent.Semaphore;
+
+/**
+ * 应用Semaphore机制
+ */
+public class AsyncResultImpl8 implements AsyncResult {
+ private volatile int result = -1;
+
+ @Override
+ public int getResult() throws Exception {
+ final Semaphore semaphore = new Semaphore(2);
+ semaphore.acquire(1);
+ new Thread(new Runnable() {
+ @Override
+ public void run() {
+ try {
+ result = sum();
+ }finally {
+ semaphore.release(1);
+ }
+ }
+ }).start();
+
+ semaphore.acquire(2);
+ return result;
+ }
+}
diff --git a/03concurrency/0301/src/main/java/java0/conc0303/homework/AsyncResultImpl9.java b/03concurrency/0301/src/main/java/java0/conc0303/homework/AsyncResultImpl9.java
new file mode 100644
index 00000000..de68464f
--- /dev/null
+++ b/03concurrency/0301/src/main/java/java0/conc0303/homework/AsyncResultImpl9.java
@@ -0,0 +1,25 @@
+package java0.conc0303.homework;
+
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+
+/**
+ * 应用Future机制
+ */
+public class AsyncResultImpl9 implements AsyncResult{
+ @Override
+ public int getResult() throws Exception{
+ ExecutorService executorService = Executors.newFixedThreadPool(1);
+ Future future = executorService.submit(new Callable() {
+ @Override
+ public Integer call() {
+ return sum();
+ }
+ });
+ // 注意关闭线程池,否则main线程不会结束,会一直等待,直到线程池被关闭。
+ executorService.shutdown();
+ return future.get();
+ }
+}
diff --git a/03concurrency/0301/src/main/java/java0/conc0303/homework/Homework.java b/03concurrency/0301/src/main/java/java0/conc0303/homework/Homework.java
new file mode 100644
index 00000000..d85ff7df
--- /dev/null
+++ b/03concurrency/0301/src/main/java/java0/conc0303/homework/Homework.java
@@ -0,0 +1,99 @@
+package java0.conc0303.homework;
+
+import org.junit.Test;
+
+/**
+ * 本周作业:(必做)思考有多少种方式,在main函数启动一个新线程或线程池,
+ * 异步运行一个方法,拿到这个方法的返回值后,退出主线程?
+ * 写出你的方法,越多越好,提交到github。
+ *
+ * 一个简单的代码参考:
+ */
+
+public class Homework {
+
+ /* public static void main(String[] args) throws Exception {
+ long start=System.currentTimeMillis();
+ AsyncResult asyncResult = new AsyncResultImpl5();
+ System.out.println("异步计算结果为:"+ asyncResult.getResult());
+ System.out.println("使用时间:"+ (System.currentTimeMillis()-start) + " ms");
+ System.out.println("退出main线程");
+ }*/
+ @Test
+ public void test1() throws Exception {
+ long start=System.currentTimeMillis();
+ AsyncResult asyncResult = new AsyncResultImpl1();
+ System.out.println("异步计算结果为:"+ asyncResult.getResult());
+ System.out.println("使用时间:"+ (System.currentTimeMillis()-start) + " ms");
+ System.out.println("退出main线程");
+ }
+
+ @Test
+ public void test2() throws Exception {
+ long start=System.currentTimeMillis();
+ AsyncResult asyncResult = new AsyncResultImpl2();
+ System.out.println("异步计算结果为:"+ asyncResult.getResult());
+ System.out.println("使用时间:"+ (System.currentTimeMillis()-start) + " ms");
+ System.out.println("退出main线程");
+ }
+
+ @Test
+ public void test3() throws Exception {
+ long start=System.currentTimeMillis();
+ AsyncResult asyncResult = new AsyncResultImpl3();
+ System.out.println("异步计算结果为:"+ asyncResult.getResult());
+ System.out.println("使用时间:"+ (System.currentTimeMillis()-start) + " ms");
+ System.out.println("退出main线程");
+ }
+
+ @Test
+ public void test4() throws Exception {
+ long start=System.currentTimeMillis();
+ AsyncResult asyncResult = new AsyncResultImpl4();
+ System.out.println("异步计算结果为:"+ asyncResult.getResult());
+ System.out.println("使用时间:"+ (System.currentTimeMillis()-start) + " ms");
+ System.out.println("退出main线程");
+ }
+
+ @Test
+ public void test6() throws Exception {
+ long start=System.currentTimeMillis();
+ AsyncResult asyncResult = new AsyncResultImpl6();
+ System.out.println("异步计算结果为:"+ asyncResult.getResult());
+ System.out.println("使用时间:"+ (System.currentTimeMillis()-start) + " ms");
+ System.out.println("退出main线程");
+ }
+ @Test
+ public void test7() throws Exception {
+ long start=System.currentTimeMillis();
+ AsyncResult asyncResult = new AsyncResultImpl7();
+ System.out.println("异步计算结果为:"+ asyncResult.getResult());
+ System.out.println("使用时间:"+ (System.currentTimeMillis()-start) + " ms");
+ System.out.println("退出main线程");
+ }
+ @Test
+ public void test8() throws Exception {
+ long start=System.currentTimeMillis();
+ AsyncResult asyncResult = new AsyncResultImpl8();
+ System.out.println("异步计算结果为:"+ asyncResult.getResult());
+ System.out.println("使用时间:"+ (System.currentTimeMillis()-start) + " ms");
+ System.out.println("退出main线程");
+ }
+ @Test
+ public void test9() throws Exception {
+ long start=System.currentTimeMillis();
+ AsyncResult asyncResult = new AsyncResultImpl9();
+ System.out.println("异步计算结果为:"+ asyncResult.getResult());
+ System.out.println("使用时间:"+ (System.currentTimeMillis()-start) + " ms");
+ System.out.println("退出main线程");
+ }
+ @Test
+ public void test10() throws Exception {
+ long start=System.currentTimeMillis();
+ AsyncResult asyncResult = new AsyncResultImpl10();
+ System.out.println("异步计算结果为:"+ asyncResult.getResult());
+ System.out.println("使用时间:"+ (System.currentTimeMillis()-start) + " ms");
+ System.out.println("退出main线程");
+ }
+
+}
diff --git a/03concurrency/0301/src/main/java/java0/conc0303/threadlocal/ThreadLocalDemo.java b/03concurrency/0301/src/main/java/java0/conc0303/threadlocal/ThreadLocalDemo.java
index bbfe35e0..411cf984 100644
--- a/03concurrency/0301/src/main/java/java0/conc0303/threadlocal/ThreadLocalDemo.java
+++ b/03concurrency/0301/src/main/java/java0/conc0303/threadlocal/ThreadLocalDemo.java
@@ -1,5 +1,8 @@
package java0.conc0303.threadlocal;
+/**
+ * Thread level variable: ThreadLocal
+ */
public class ThreadLocalDemo {
private static ThreadLocal seqNum = new ThreadLocal() {
diff --git a/03concurrency/0301/src/main/java/java0/conc0303/tool/CountDownLatchDemo.java b/03concurrency/0301/src/main/java/java0/conc0303/tool/CountDownLatchDemo.java
index b93731be..5e847033 100644
--- a/03concurrency/0301/src/main/java/java0/conc0303/tool/CountDownLatchDemo.java
+++ b/03concurrency/0301/src/main/java/java0/conc0303/tool/CountDownLatchDemo.java
@@ -2,6 +2,9 @@
import java.util.concurrent.CountDownLatch;
+/**
+ * CountDownLatch 各个线程相对独立影响CountDownLatch 状态,最后在主线程上汇聚
+ */
public class CountDownLatchDemo {
public static void main(String[] args) throws InterruptedException {
CountDownLatch countDownLatch = new CountDownLatch(5);
@@ -22,12 +25,12 @@ public readNum(int id,CountDownLatch latch){
}
@Override
public void run() {
- synchronized (this){
+ //synchronized (this){
System.out.println("id:"+id+","+Thread.currentThread().getName());
//latch.countDown();
System.out.println("线程组任务"+id+"结束,其他任务继续");
latch.countDown();
- }
+ //}
}
}
}
\ No newline at end of file
diff --git a/03concurrency/0301/src/main/java/java0/conc0303/tool/CyclicBarrierDemo.java b/03concurrency/0301/src/main/java/java0/conc0303/tool/CyclicBarrierDemo.java
index 628d980d..58b2d14d 100644
--- a/03concurrency/0301/src/main/java/java0/conc0303/tool/CyclicBarrierDemo.java
+++ b/03concurrency/0301/src/main/java/java0/conc0303/tool/CyclicBarrierDemo.java
@@ -2,6 +2,11 @@
import java.util.concurrent.CyclicBarrier;
+/**
+ * CyclicBarrier 线程之间不相关独立,随着线程影响CyclicBarrier的状态,线程间状态相互影响,
+ * 当线程内部到达cyc.await() 进行阻塞,直到所有线程都达到cyc.await()处,内部线程进行执行,
+ * 最后到达cyc.await()的线程,还会调用回调函数的run方法,进行回调处理。
+ */
public class CyclicBarrierDemo {
public static void main(String[] args) throws InterruptedException {
CyclicBarrier cyclicBarrier = new CyclicBarrier(5, new Runnable() {
@@ -36,16 +41,16 @@ public readNum(int id,CyclicBarrier cyc){
}
@Override
public void run() {
- synchronized (this){
+ //synchronized (this){
System.out.println("id:"+id+","+Thread.currentThread().getName());
try {
- cyc.await();
+ ///cyc.await();
System.out.println("线程组任务" + id + "结束,其他任务继续");
- //cyc.await(); // 注意跟CountDownLatch不同,这里在子线程await
+ cyc.await(); // 注意跟CountDownLatch不同,这里在子线程await
} catch (Exception e) {
e.printStackTrace();
}
- }
+ //}
}
}
}
\ No newline at end of file
diff --git a/03concurrency/0301/src/main/java/java0/conc0303/tool/SemaphoreDemo2.java b/03concurrency/0301/src/main/java/java0/conc0303/tool/SemaphoreDemo2.java
index 2acb724a..8fc605fa 100644
--- a/03concurrency/0301/src/main/java/java0/conc0303/tool/SemaphoreDemo2.java
+++ b/03concurrency/0301/src/main/java/java0/conc0303/tool/SemaphoreDemo2.java
@@ -19,6 +19,7 @@ public static void main(String[] args) throws Exception {
exec.execute(() -> {
try {
semaphore.acquire(3); // 获取全部许可,退化成串行执行
+ Thread.sleep(3000);
test(threadNum);
semaphore.release(3); // 释放多个许可
} catch (Exception e) {