diff --git a/02nio/nio02/src/main/java/io/github/kimmking/gateway/router/HttpEndpointRouter.java b/02nio/nio02/src/main/java/io/github/kimmking/gateway/router/HttpEndpointRouter.java index f921330a..8e307ab7 100644 --- a/02nio/nio02/src/main/java/io/github/kimmking/gateway/router/HttpEndpointRouter.java +++ b/02nio/nio02/src/main/java/io/github/kimmking/gateway/router/HttpEndpointRouter.java @@ -6,4 +6,12 @@ public interface HttpEndpointRouter { String route(List endpoints); + // Load Balance + // Random + // RoundRibbon + // Weight + // - server01,20 + // - server02,30 + // - server03,50 + } diff --git a/03concurrency/0301/src/main/java/java0/conc0301/DaemonThread.java b/03concurrency/0301/src/main/java/java0/conc0301/DaemonThread.java index 8d985a55..5a00ab24 100644 --- a/03concurrency/0301/src/main/java/java0/conc0301/DaemonThread.java +++ b/03concurrency/0301/src/main/java/java0/conc0301/DaemonThread.java @@ -17,7 +17,7 @@ public void run() { }; Thread thread = new Thread(task); thread.setName("test-thread-1"); - thread.setDaemon(true); + thread.setDaemon(false); thread.start(); } diff --git a/03concurrency/0301/src/main/java/java0/conc0301/Runner2.java b/03concurrency/0301/src/main/java/java0/conc0301/Runner2.java index c9ff3b96..d80e8c14 100644 --- a/03concurrency/0301/src/main/java/java0/conc0301/Runner2.java +++ b/03concurrency/0301/src/main/java/java0/conc0301/Runner2.java @@ -11,11 +11,13 @@ public void run() { boolean result = Thread.currentThread().isInterrupted(); boolean result1 = Thread.interrupted(); // 重置状态 - + boolean result3 = Thread.currentThread().isInterrupted(); System.out.println("Runner2.run result ===>" + result); System.out.println("Runner2.run result1 ===>" + result1); System.out.println("Runner2.run result3 ===>" + result3); + + } } diff --git a/03concurrency/0301/src/main/java/java0/conc0301/RunnerMain.java b/03concurrency/0301/src/main/java/java0/conc0301/RunnerMain.java index 4526412e..626f2d38 100644 --- a/03concurrency/0301/src/main/java/java0/conc0301/RunnerMain.java +++ b/03concurrency/0301/src/main/java/java0/conc0301/RunnerMain.java @@ -1,9 +1,11 @@ package java0.conc0301; +import java.io.IOException; + public class RunnerMain { - public static void main(String[] args) { + public static void main(String[] args) throws IOException { Runner1 runner1 = new Runner1(); Thread thread1 = new Thread(runner1); @@ -14,12 +16,14 @@ public static void main(String[] args) { thread1.start(); thread2.start(); - thread2.interrupt(); + thread2.interrupt(); // i = true System.out.println(Thread.activeCount()); -// Thread.currentThread().getThreadGroup().list(); -// System.out.println(Thread.currentThread().getThreadGroup().getParent().activeGroupCount()); -// Thread.currentThread().getThreadGroup().getParent().list(); + Thread.currentThread().getThreadGroup().list(); + System.out.println(Thread.currentThread().getThreadGroup().getParent().activeGroupCount()); + Thread.currentThread().getThreadGroup().getParent().list(); + + } } diff --git a/03concurrency/0301/src/main/java/java0/conc0301/ThreadB.java b/03concurrency/0301/src/main/java/java0/conc0301/ThreadB.java index 0b0ad326..fe7dda58 100644 --- a/03concurrency/0301/src/main/java/java0/conc0301/ThreadB.java +++ b/03concurrency/0301/src/main/java/java0/conc0301/ThreadB.java @@ -15,7 +15,7 @@ public void run() { String currentThreadName = currentThread.getName(); System.out.println("这是线程的名称:" + currentThreadName); - System.out.println("返回当前线程" + currentThreadName + "的线程组中活动线程的数量:" + Thread.activeCount()); + System.out.println("返回当前线程" + currentThreadName + "的线程组中活动线程的数量:" + Thread.currentThread().getThreadGroup().activeCount()); System.out.println("返回该线程" + currentThreadName + "的标识符:" + currentThread.getId()); System.out.println("返回该线程" + currentThreadName + "的优先级:" + currentThread.getPriority()); System.out.println("返回该线程" + currentThreadName + "的状态:" + currentThread.getState()); diff --git a/03concurrency/0301/src/main/java/java0/conc0301/ThreadMain.java b/03concurrency/0301/src/main/java/java0/conc0301/ThreadMain.java index 3a12ddb7..5478e112 100644 --- a/03concurrency/0301/src/main/java/java0/conc0301/ThreadMain.java +++ b/03concurrency/0301/src/main/java/java0/conc0301/ThreadMain.java @@ -15,7 +15,7 @@ public static void main(String[] args) { new Thread(threadB).start(); System.out.println("这是主线程:"); - ThreadC threadC = new ThreadC(); + ThreadC threadC = new ThreadC(); FutureTask futureTask = new FutureTask<>(threadC); new Thread(futureTask).start(); System.out.println("这是主线程:begin!"); 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 13fadb19..5e60163a 100644 --- a/03concurrency/0301/src/main/java/java0/conc0301/op/Join.java +++ b/03concurrency/0301/src/main/java/java0/conc0301/op/Join.java @@ -9,7 +9,7 @@ public static void main(String[] args) { thread1.setOo(oo); thread1.start(); - synchronized (oo) { + synchronized (thread1) { for (int i = 0; i < 100; i++) { if (i == 20) { try { @@ -40,7 +40,7 @@ public MyThread(String name) { @Override public void run() { - synchronized (oo) { + synchronized (this) { for (int i = 0; i < 100; i++) { System.out.println(name + i); } 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 bd3e1e4e..e3956c10 100644 --- a/03concurrency/0301/src/main/java/java0/conc0301/op/WaitAndNotify.java +++ b/03concurrency/0301/src/main/java/java0/conc0301/op/WaitAndNotify.java @@ -19,17 +19,17 @@ public static void main(String[] args) { e.printStackTrace(); } }, "t2"); - Thread t3 = new Thread(() -> { - try { - methodClass.customer(); - } catch (InterruptedException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - }, "t3"); +// Thread t3 = new Thread(() -> { +// try { +// methodClass.customer(); +// } catch (InterruptedException e) { +// // TODO Auto-generated catch block +// e.printStackTrace(); +// } +// }, "t3"); t1.start(); t2.start(); - t3.start(); + //t3.start(); } } 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 a066caf8..e60845a6 100644 --- a/03concurrency/0301/src/main/java/java0/conc0301/sync/Counter.java +++ b/03concurrency/0301/src/main/java/java0/conc0301/sync/Counter.java @@ -1,16 +1,21 @@ package java0.conc0301.sync; public class Counter { - private int sum = 0; - public void incr() { - sum++; + + public final static int A=10; + + public static int B=10; + + private volatile int sum = 0; + public synchronized void incr() { + sum=sum+1; } public int getSum() { return sum; } public static void main(String[] args) throws InterruptedException { - int loop = 10000; + int loop = 100000; // test single thread Counter counter = new Counter(); @@ -33,10 +38,10 @@ public static void main(String[] args) throws InterruptedException { }); t1.start(); t2.start(); - //Thread.sleep(300); - while (Thread.activeCount()>2){//当前线程的线程组中的数量>2 - Thread.yield(); - } + Thread.sleep(1000); +// while (Thread.activeCount()>2){//当前线程的线程组中的数量>2 +// Thread.yield(); +// } System.out.println("multiple threads: " + counter2.getSum()); diff --git a/03concurrency/0301/src/main/java/java0/conc0301/sync/Cref.java b/03concurrency/0301/src/main/java/java0/conc0301/sync/Cref.java new file mode 100644 index 00000000..f80742b0 --- /dev/null +++ b/03concurrency/0301/src/main/java/java0/conc0301/sync/Cref.java @@ -0,0 +1,8 @@ +package java0.conc0301.sync; + +public class Cref { + public static void main(String[] args) { + int x = 10; + int y = Counter.B; + } +} diff --git a/03concurrency/0301/src/main/java/java0/conc0302/atomic/AtomicCount.java b/03concurrency/0301/src/main/java/java0/conc0302/atomic/AtomicCount.java new file mode 100644 index 00000000..cece1ec3 --- /dev/null +++ b/03concurrency/0301/src/main/java/java0/conc0302/atomic/AtomicCount.java @@ -0,0 +1,17 @@ + +package java0.conc0302.atomic; + +import java.util.concurrent.atomic.AtomicInteger; + +public class AtomicCount { + + private AtomicInteger num = new AtomicInteger(); + + public int add() { + return num.getAndIncrement(); + } + + public int getNum() { + return num.get(); + } +} diff --git a/03concurrency/0301/src/main/java/java0/conc0302/atomic/AtomicMain.java b/03concurrency/0301/src/main/java/java0/conc0302/atomic/AtomicMain.java new file mode 100644 index 00000000..de251e57 --- /dev/null +++ b/03concurrency/0301/src/main/java/java0/conc0302/atomic/AtomicMain.java @@ -0,0 +1,28 @@ + +package java0.conc0302.atomic; + +public class AtomicMain { + + public static void main(String[] args) { + final AtomicCount count = new AtomicCount(); + for (int i = 0; i < 100; i++) { + new Thread(new Runnable() { + @Override + public void run() { + for (int j = 0; j < 10000; j++) { + count.add(); + } + } + }).start(); + } + + try { + Thread.sleep(1000L); + } catch (InterruptedException e) { + e.printStackTrace(); + } + + System.out.println("num=" + count.getNum()); + } + +} diff --git a/03concurrency/0301/src/main/java/java0/conc0302/atomic/Count.java b/03concurrency/0301/src/main/java/java0/conc0302/atomic/Count.java new file mode 100644 index 00000000..02fd13d5 --- /dev/null +++ b/03concurrency/0301/src/main/java/java0/conc0302/atomic/Count.java @@ -0,0 +1,15 @@ + +package java0.conc0302.atomic; + +public class Count { + + private int num = 0; + + public int add() { + return num++; + } + + public int getNum() { + return num; + } +} diff --git a/03concurrency/0301/src/main/java/java0/conc0302/atomic/LongDemo.java b/03concurrency/0301/src/main/java/java0/conc0302/atomic/LongDemo.java new file mode 100644 index 00000000..6a7356c6 --- /dev/null +++ b/03concurrency/0301/src/main/java/java0/conc0302/atomic/LongDemo.java @@ -0,0 +1,35 @@ +package java0.conc0302.atomic; + +import java.util.concurrent.atomic.AtomicLong; +import java.util.concurrent.atomic.LongAdder; + +public class LongDemo { + + public static void main(String[] args) { + + final AtomicLong atomicLong = new AtomicLong(); + final LongAdder longAdder = new LongAdder(); + + for (int i = 0; i < 100; i++) { + new Thread(new Runnable() { + @Override + public void run() { + for (int j = 0; j < 10000; j++) { + atomicLong.getAndIncrement(); + longAdder.increment(); + } + } + }).start(); + } + + try { + Thread.sleep(1000L); + } catch (InterruptedException e) { + e.printStackTrace(); + } + + System.out.println("atomicLong=" + atomicLong.get()); + System.out.println("longAdder =" + longAdder.sum()); + + } +} diff --git a/03concurrency/0301/src/main/java/java0/conc0302/atomic/SyncCount.java b/03concurrency/0301/src/main/java/java0/conc0302/atomic/SyncCount.java new file mode 100644 index 00000000..5a32183e --- /dev/null +++ b/03concurrency/0301/src/main/java/java0/conc0302/atomic/SyncCount.java @@ -0,0 +1,15 @@ + +package java0.conc0302.atomic; + +public class SyncCount { + + private int num = 0; + + public synchronized int add() { + return num++; + } + + public int getNum() { + return num; + } +} diff --git a/03concurrency/0301/src/main/java/java0/conc0302/lock/ConditionDemo.java b/03concurrency/0301/src/main/java/java0/conc0302/lock/ConditionDemo.java new file mode 100644 index 00000000..33ad0bab --- /dev/null +++ b/03concurrency/0301/src/main/java/java0/conc0302/lock/ConditionDemo.java @@ -0,0 +1,45 @@ +package java0.conc0302.lock; + +import java.util.concurrent.locks.Condition; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; + +class ConditionDemo { + final Lock lock = new ReentrantLock(); + final Condition notFull = lock.newCondition(); + final Condition notEmpty = lock.newCondition(); + + final Object[] items = new Object[20]; + int putptr, takeptr, count; + + public void put(Object x) throws InterruptedException { + lock.lock(); + try { + // 当count等于数组的大小时,当前线程等待,直到notFull通知,再进行生产 + while (count == items.length) + notFull.await(); + items[putptr] = x; + if (++putptr == items.length) putptr = 0; + ++count; + notEmpty.signal(); + } finally { + lock.unlock(); + } + } + + public Object take() throws InterruptedException { + lock.lock(); + try { + // 当count为0,进入等待,直到notEmpty通知,进行消费。 + while (count == 0) + notEmpty.await(); + Object x = items[takeptr]; + if (++takeptr == items.length) takeptr = 0; + --count; + notFull.signal(); + return x; + } finally { + lock.unlock(); + } + } +} \ No newline at end of file diff --git a/03concurrency/0301/src/main/java/java0/conc0302/lock/Count.java b/03concurrency/0301/src/main/java/java0/conc0302/lock/Count.java new file mode 100644 index 00000000..09197048 --- /dev/null +++ b/03concurrency/0301/src/main/java/java0/conc0302/lock/Count.java @@ -0,0 +1,35 @@ + +package java0.conc0302.lock; + +import java.util.concurrent.locks.ReentrantLock; + +public class Count { + + final ReentrantLock lock = new ReentrantLock(); + + public void get() { +// final ReentrantLock lock = new ReentrantLock(); + try { + lock.lock(); + System.out.println(Thread.currentThread().getName() + " get begin"); + Thread.sleep(1000); + System.out.println(Thread.currentThread().getName() + " get end"); + lock.unlock(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + + public void put() { +// final ReentrantLock lock = new ReentrantLock(); + try { + lock.lock(); + System.out.println(Thread.currentThread().getName() + " put begin"); + Thread.sleep(1000); + System.out.println(Thread.currentThread().getName() + " put end"); + lock.unlock(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } +} diff --git a/03concurrency/0301/src/main/java/java0/conc0302/lock/Count2.java b/03concurrency/0301/src/main/java/java0/conc0302/lock/Count2.java new file mode 100644 index 00000000..8cd691d1 --- /dev/null +++ b/03concurrency/0301/src/main/java/java0/conc0302/lock/Count2.java @@ -0,0 +1,35 @@ + +package java0.conc0302.lock; + +import java.util.concurrent.locks.ReentrantReadWriteLock; + +public class Count2 { + + private final ReentrantReadWriteLock rwLock = new ReentrantReadWriteLock(); + + public void get() { + rwLock.readLock().lock(); + try { + System.out.println(Thread.currentThread().getName() + " get begin"); + Thread.sleep(1000); + System.out.println(Thread.currentThread().getName() + " get end"); + } catch (InterruptedException e) { + e.printStackTrace(); + } finally { + rwLock.readLock().unlock(); + } + } + + public void put() { + rwLock.writeLock().lock(); + try { + System.out.println(Thread.currentThread().getName() + " put begin"); + Thread.sleep(1000); + System.out.println(Thread.currentThread().getName() + " put end"); + } catch (InterruptedException e) { + e.printStackTrace(); + } finally { + rwLock.writeLock().unlock(); + } + } +} diff --git a/03concurrency/0301/src/main/java/java0/conc0302/lock/Count3.java b/03concurrency/0301/src/main/java/java0/conc0302/lock/Count3.java new file mode 100644 index 00000000..f99eaa3e --- /dev/null +++ b/03concurrency/0301/src/main/java/java0/conc0302/lock/Count3.java @@ -0,0 +1,40 @@ + +package java0.conc0302.lock; + +public class Count3 { + + private byte[] lock1 = new byte[1]; + private byte[] lock2 = new byte[1]; + + public int num = 0; + + public void add() { + synchronized (lock1) { + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + synchronized (lock2) { + num += 1; + } + System.out.println(Thread.currentThread().getName() + "_" + num); + } + } + + public void lockMethod() { + synchronized (lock2) { + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + synchronized (lock1) { + num += 1; + } + System.out.println(Thread.currentThread().getName() + "_" + num); + } + } + + +} diff --git a/03concurrency/0301/src/main/java/java0/conc0302/lock/LockMain.java b/03concurrency/0301/src/main/java/java0/conc0302/lock/LockMain.java new file mode 100644 index 00000000..e8f203e2 --- /dev/null +++ b/03concurrency/0301/src/main/java/java0/conc0302/lock/LockMain.java @@ -0,0 +1,18 @@ + +package java0.conc0302.lock; + +public class LockMain { + + public static void main(String[] args) { + Count3 count3 = new Count3(); + ThreadA threadA = new ThreadA(count3); + threadA.setName("线程A"); + threadA.start(); + + ThreadB threadB = new ThreadB(count3); + threadB.setName("线程B"); + threadB.start(); + + } + +} diff --git a/03concurrency/0301/src/main/java/java0/conc0302/lock/LockSupportDemo.java b/03concurrency/0301/src/main/java/java0/conc0302/lock/LockSupportDemo.java new file mode 100644 index 00000000..18f598f1 --- /dev/null +++ b/03concurrency/0301/src/main/java/java0/conc0302/lock/LockSupportDemo.java @@ -0,0 +1,37 @@ +package java0.conc0302.lock; + +import java.util.concurrent.locks.LockSupport; + +public class LockSupportDemo { + + public static Object u = new Object(); + static ChangeObjectThread t1 = new ChangeObjectThread("t1"); + static ChangeObjectThread t2 = new ChangeObjectThread("t2"); + + public static class ChangeObjectThread extends Thread { + public ChangeObjectThread(String name) { + super(name); + } + @Override public void run() { + synchronized (u) { + System.out.println("in " + getName()); + LockSupport.park(); + if (Thread.currentThread().isInterrupted()) { + System.out.println("被中断了"); + } + System.out.println("继续执行"); + } + } + } + + public static void main(String[] args) throws InterruptedException { + t1.start(); + Thread.sleep(1000L); + t2.start(); + Thread.sleep(3000L); + t1.interrupt(); + LockSupport.unpark(t2); + t1.join(); + t2.join(); + } +} \ No newline at end of file diff --git a/03concurrency/0301/src/main/java/java0/conc0302/lock/ObjectCache.java b/03concurrency/0301/src/main/java/java0/conc0302/lock/ObjectCache.java new file mode 100644 index 00000000..1dc4cee0 --- /dev/null +++ b/03concurrency/0301/src/main/java/java0/conc0302/lock/ObjectCache.java @@ -0,0 +1,77 @@ + +package java0.conc0302.lock; + +import java.util.concurrent.Semaphore; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; + +public class ObjectCache { + + public interface ObjectFactory { + T makeObject(); + } + + class Node { + T obj; + Node next; + } + + final int capacity; + final ObjectFactory factory; + final Lock lock = new ReentrantLock(); + final Semaphore semaphore; + private Node head; + private Node tail; + + public ObjectCache(int capacity, ObjectFactory factory) { + this.capacity = capacity; + this.factory = factory; + this.semaphore = new Semaphore(this.capacity); + this.head = null; + this.tail = null; + } + + public T getObject() throws InterruptedException { + semaphore.acquire(); + return getNextObject(); + } + + private T getNextObject() { + lock.lock(); + try { + if (head == null) { + return factory.makeObject(); + } else { + Node ret = head; + head = head.next; + if (head == null) tail = null; + ret.next = null;//help GC + return ret.obj; + } + } finally { + lock.unlock(); + } + } + + private void returnObjectToPool(T t) { + lock.lock(); + try { + Node node = new Node(); + node.obj = t; + if (tail == null) { + head = tail = node; + } else { + tail.next = node; + tail = node; + } + + } finally { + lock.unlock(); + } + } + + public void returnObject(T t) { + returnObjectToPool(t); + semaphore.release(); + } +} diff --git a/03concurrency/0301/src/main/java/java0/conc0302/lock/ReentrantLockDemo.java b/03concurrency/0301/src/main/java/java0/conc0302/lock/ReentrantLockDemo.java new file mode 100644 index 00000000..d0ff5f98 --- /dev/null +++ b/03concurrency/0301/src/main/java/java0/conc0302/lock/ReentrantLockDemo.java @@ -0,0 +1,25 @@ + +package java0.conc0302.lock; + +public class ReentrantLockDemo { + + public static void main(String[] args) { + final Count count = new Count(); + + for (int i = 0; i < 2; i++) { + new Thread() { + public void run() { + count.get(); + } + }.start(); + } + + for (int i = 0; i < 2; i++) { + new Thread() { + public void run() { + count.put(); + } + }.start(); + } + } +} diff --git a/03concurrency/0301/src/main/java/java0/conc0302/lock/ReentrantReadWriteLockDemo.java b/03concurrency/0301/src/main/java/java0/conc0302/lock/ReentrantReadWriteLockDemo.java new file mode 100644 index 00000000..e36e3375 --- /dev/null +++ b/03concurrency/0301/src/main/java/java0/conc0302/lock/ReentrantReadWriteLockDemo.java @@ -0,0 +1,51 @@ + +package java0.conc0302.lock; + +public class ReentrantReadWriteLockDemo { + + public static void main(String[] args) { + final Count2 count = new Count2(); + + for (int i = 0; i < 5; i++) { + new Thread() { + public void run() { + count.get(); + } + }.start(); + } + + for (int i = 0; i < 5; i++) { + new Thread() { + public void run() { + count.put(); + } + }.start(); + } + } + + /** + * + * Thread-0 get begin + Thread-1 get begin + Thread-2 get begin + Thread-3 get begin + Thread-4 get begin + Thread-0 get end + Thread-1 get end + Thread-2 get end + Thread-4 get end + Thread-3 get end + Thread-5 put begin + Thread-5 put end + Thread-6 put begin + Thread-6 put end + Thread-7 put begin + Thread-7 put end + Thread-8 put begin + Thread-8 put end + Thread-9 put begin + Thread-9 put end + * + */ + // 读锁不互斥、写锁互斥 +} diff --git a/03concurrency/0301/src/main/java/java0/conc0302/lock/ReentrantReadWriteLockDemo2.java b/03concurrency/0301/src/main/java/java0/conc0302/lock/ReentrantReadWriteLockDemo2.java new file mode 100644 index 00000000..82b4001b --- /dev/null +++ b/03concurrency/0301/src/main/java/java0/conc0302/lock/ReentrantReadWriteLockDemo2.java @@ -0,0 +1,47 @@ + +package java0.conc0302.lock; + +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.locks.ReentrantReadWriteLock; + +public class ReentrantReadWriteLockDemo2 { + + 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"; + } + } finally { + System.out.println("3.释放写锁"); + rwLock.writeLock().unlock(); + } + System.out.println("4.开启读锁"); + rwLock.readLock().lock(); + } + } finally { + System.out.println("5.释放读锁"); + rwLock.readLock().unlock(); + } + return value; + } + + public static void main(String[] args) { + ReentrantReadWriteLockDemo2 demo2 = new ReentrantReadWriteLockDemo2(); + demo2.readWrite("bingfabiancheng"); + } + +} diff --git a/03concurrency/0301/src/main/java/java0/conc0302/lock/ThreadA.java b/03concurrency/0301/src/main/java/java0/conc0302/lock/ThreadA.java new file mode 100644 index 00000000..5bc7d65a --- /dev/null +++ b/03concurrency/0301/src/main/java/java0/conc0302/lock/ThreadA.java @@ -0,0 +1,15 @@ + +package java0.conc0302.lock; + +public class ThreadA extends Thread { + private Count3 count3; + + public ThreadA(Count3 count3) { + this.count3 = count3; + } + + public void run() { + count3.add(); + } + +} diff --git a/03concurrency/0301/src/main/java/java0/conc0302/lock/ThreadB.java b/03concurrency/0301/src/main/java/java0/conc0302/lock/ThreadB.java new file mode 100644 index 00000000..ee6942f1 --- /dev/null +++ b/03concurrency/0301/src/main/java/java0/conc0302/lock/ThreadB.java @@ -0,0 +1,15 @@ + +package java0.conc0302.lock; + +public class ThreadB extends Thread { + private Count3 count3; + + public ThreadB(Count3 count3) { + this.count3 = count3; + } + + public void run() { + count3.lockMethod(); + } + +} diff --git a/03concurrency/0301/src/main/java/java0/conc0301/threadpool/ExecutorServiceDemo.java b/03concurrency/0301/src/main/java/java0/conc0302/threadpool/ExecutorServiceDemo.java similarity index 95% rename from 03concurrency/0301/src/main/java/java0/conc0301/threadpool/ExecutorServiceDemo.java rename to 03concurrency/0301/src/main/java/java0/conc0302/threadpool/ExecutorServiceDemo.java index cc777c9a..664b6942 100644 --- a/03concurrency/0301/src/main/java/java0/conc0301/threadpool/ExecutorServiceDemo.java +++ b/03concurrency/0301/src/main/java/java0/conc0302/threadpool/ExecutorServiceDemo.java @@ -1,5 +1,5 @@ -package java0.conc0301.threadpool; +package java0.conc0302.threadpool; import java.util.concurrent.Callable; import java.util.concurrent.Executors; diff --git a/03concurrency/0301/src/main/java/java0/conc0301/threadpool/NewCachedThreadPoolDemo.java b/03concurrency/0301/src/main/java/java0/conc0302/threadpool/NewCachedThreadPoolDemo.java similarity index 96% rename from 03concurrency/0301/src/main/java/java0/conc0301/threadpool/NewCachedThreadPoolDemo.java rename to 03concurrency/0301/src/main/java/java0/conc0302/threadpool/NewCachedThreadPoolDemo.java index 69cb8a6e..2137af53 100644 --- a/03concurrency/0301/src/main/java/java0/conc0301/threadpool/NewCachedThreadPoolDemo.java +++ b/03concurrency/0301/src/main/java/java0/conc0302/threadpool/NewCachedThreadPoolDemo.java @@ -1,5 +1,5 @@ -package java0.conc0301.threadpool; +package java0.conc0302.threadpool; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; diff --git a/03concurrency/0301/src/main/java/java0/conc0301/threadpool/NewFixedThreadExecutorDemo.java b/03concurrency/0301/src/main/java/java0/conc0302/threadpool/NewFixedThreadExecutorDemo.java similarity index 95% rename from 03concurrency/0301/src/main/java/java0/conc0301/threadpool/NewFixedThreadExecutorDemo.java rename to 03concurrency/0301/src/main/java/java0/conc0302/threadpool/NewFixedThreadExecutorDemo.java index 19bc39bc..9f7dba25 100644 --- a/03concurrency/0301/src/main/java/java0/conc0301/threadpool/NewFixedThreadExecutorDemo.java +++ b/03concurrency/0301/src/main/java/java0/conc0302/threadpool/NewFixedThreadExecutorDemo.java @@ -1,5 +1,5 @@ -package java0.conc0301.threadpool; +package java0.conc0302.threadpool; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; diff --git a/03concurrency/0301/src/main/java/java0/conc0301/threadpool/NewScheduledThreadExecutorDemo.java b/03concurrency/0301/src/main/java/java0/conc0302/threadpool/NewScheduledThreadExecutorDemo.java similarity index 96% rename from 03concurrency/0301/src/main/java/java0/conc0301/threadpool/NewScheduledThreadExecutorDemo.java rename to 03concurrency/0301/src/main/java/java0/conc0302/threadpool/NewScheduledThreadExecutorDemo.java index 9186d21b..3a618f0c 100644 --- a/03concurrency/0301/src/main/java/java0/conc0301/threadpool/NewScheduledThreadExecutorDemo.java +++ b/03concurrency/0301/src/main/java/java0/conc0302/threadpool/NewScheduledThreadExecutorDemo.java @@ -1,5 +1,5 @@ -package java0.conc0301.threadpool; +package java0.conc0302.threadpool; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; diff --git a/03concurrency/0301/src/main/java/java0/conc0301/threadpool/NewSingleThreadExecutorDemo.java b/03concurrency/0301/src/main/java/java0/conc0302/threadpool/NewSingleThreadExecutorDemo.java similarity index 95% rename from 03concurrency/0301/src/main/java/java0/conc0301/threadpool/NewSingleThreadExecutorDemo.java rename to 03concurrency/0301/src/main/java/java0/conc0302/threadpool/NewSingleThreadExecutorDemo.java index e328ca83..dee7b07c 100644 --- a/03concurrency/0301/src/main/java/java0/conc0301/threadpool/NewSingleThreadExecutorDemo.java +++ b/03concurrency/0301/src/main/java/java0/conc0302/threadpool/NewSingleThreadExecutorDemo.java @@ -1,5 +1,5 @@ -package java0.conc0301.threadpool; +package java0.conc0302.threadpool; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; diff --git a/03concurrency/0301/src/main/java/java0/conc0303/Homework03.java b/03concurrency/0301/src/main/java/java0/conc0303/Homework03.java new file mode 100644 index 00000000..3e64fc85 --- /dev/null +++ b/03concurrency/0301/src/main/java/java0/conc0303/Homework03.java @@ -0,0 +1,37 @@ +package java0.conc0303; + +/** + * 本周作业:(必做)思考有多少种方式,在main函数启动一个新线程或线程池, + * 异步运行一个方法,拿到这个方法的返回值后,退出主线程? + * 写出你的方法,越多越好,提交到github。 + * + * 一个简单的代码参考: + */ +public class Homework03 { + + public static void main(String[] args) { + + long start=System.currentTimeMillis(); + // 在这里创建一个线程或线程池, + // 异步执行 下面方法 + + int result = sum(); //这是得到的返回值 + + // 确保 拿到result 并输出 + System.out.println("异步计算结果为:"+result); + + System.out.println("使用时间:"+ (System.currentTimeMillis()-start) + " ms"); + + // 然后退出main线程 + } + + private static int sum() { + return fibo(36); + } + + private static 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/collection/ConcurrentHashMapDemo.java b/03concurrency/0301/src/main/java/java0/conc0303/collection/ConcurrentHashMapDemo.java new file mode 100644 index 00000000..1ec7f12b --- /dev/null +++ b/03concurrency/0301/src/main/java/java0/conc0303/collection/ConcurrentHashMapDemo.java @@ -0,0 +1,46 @@ +package java0.conc0303.collection; + +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.atomic.AtomicInteger; + +public class ConcurrentHashMapDemo { + + public static void main(String[] args) { + demo1(); + } + + public static void demo1() { + final Map count = new ConcurrentHashMap<>(); + final CountDownLatch endLatch = new CountDownLatch(2); + Runnable task = new Runnable() { + @Override + public void run() { + AtomicInteger oldValue; + for (int i = 0; i < 5; i++) { + oldValue = count.get("a"); + if (null == oldValue) { + AtomicInteger zeroValue = new AtomicInteger(0); + oldValue = count.putIfAbsent("a", zeroValue); + if (null == oldValue) { + oldValue = zeroValue; + } + } + oldValue.incrementAndGet(); + } + endLatch.countDown(); + } + }; + new Thread(task).start(); + new Thread(task).start(); + + try { + endLatch.await(); + System.out.println(count); + } catch (Exception e) { + e.printStackTrace(); + } + } + +} diff --git a/03concurrency/0301/src/main/java/java0/conc0303/collection/CopyOnWriteArrayListDemo.java b/03concurrency/0301/src/main/java/java0/conc0303/collection/CopyOnWriteArrayListDemo.java new file mode 100644 index 00000000..9b305cbd --- /dev/null +++ b/03concurrency/0301/src/main/java/java0/conc0303/collection/CopyOnWriteArrayListDemo.java @@ -0,0 +1,69 @@ +package java0.conc0303.collection; + +import java.util.ArrayList; +import java.util.LinkedList; +import java.util.List; +import java.util.Vector; +import java.util.concurrent.CopyOnWriteArrayList; + +public class CopyOnWriteArrayListDemo { + + public static void main(String[] args) { + + // ArrayList,LinkedList,Vector不安全,运行报错 + // why Vector 也不安全 +// List list = new ArrayList(); +// List list = new LinkedList<>(); +// List list = new Vector<>(); + + // 只有CopyOnWriteArrayList 安全,不报错 + List list = new CopyOnWriteArrayList(); + + for (int i = 0; i < 10000; i++) + { + list.add(i); + } + + T1 t1 = new T1(list); + T2 t2 = new T2(list); + t1.start(); + t2.start(); + + } + + public static class T1 extends Thread + { + private List list; + + public T1(List list) + { + this.list = list; + } + + public void run() + { + for (Integer i : list) + { + } + } + } + + public static class T2 extends Thread + { + private List list; + + public T2(List list) + { + this.list = list; + } + + public void run() + { + for (int i = 0; i < list.size(); i++) + { + list.remove(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 new file mode 100644 index 00000000..b99bf181 --- /dev/null +++ b/03concurrency/0301/src/main/java/java0/conc0303/collection/CopyOnWriteArrayListDemo1.java @@ -0,0 +1,69 @@ +package java0.conc0303.collection; + +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.CopyOnWriteArrayList; +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<>(); + + public static void main(String args[]) { + new CopyOnWriteArrayListDemo1().start(); + } + + private void initData() { + for (int i = 0; i <= THREAD_POOL_MAX_NUM; i++) { + this.mList.add("...... Line " + (i + 1) + " ......"); + } + } + + private void start() { + initData(); + ExecutorService service = Executors.newFixedThreadPool(THREAD_POOL_MAX_NUM); + for (int i = 0; i < THREAD_POOL_MAX_NUM; i++) { + service.execute(new ListReader(this.mList)); + service.execute(new ListWriter(this.mList, i)); + } + service.shutdown(); + } + + private class ListReader implements Runnable { + private List mList; + + public ListReader(List list) { + this.mList = list; + } + + @Override + public void run() { + if (this.mList != null) { + for (String str : this.mList) { + System.out.println(Thread.currentThread().getName() + " : " + str); + } + } + } + } + + private class ListWriter implements Runnable { + private List mList; + private int mIndex; + + public ListWriter(List list, int index) { + this.mList = list; + this.mIndex = index; + } + + @Override + public void run() { + if (this.mList != null) { + //this.mList.remove(this.mIndex); + this.mList.add("...... add " + mIndex + " ......"); + } + } + } +} \ No newline at end of file diff --git a/03concurrency/0301/src/main/java/java0/conc0303/collection/CopyOnWriteArrayListDemo2.java b/03concurrency/0301/src/main/java/java0/conc0303/collection/CopyOnWriteArrayListDemo2.java new file mode 100644 index 00000000..94ae2427 --- /dev/null +++ b/03concurrency/0301/src/main/java/java0/conc0303/collection/CopyOnWriteArrayListDemo2.java @@ -0,0 +1,51 @@ +package java0.conc0303.collection; + +import java.util.concurrent.CopyOnWriteArrayList; + +public class CopyOnWriteArrayListDemo2 { + + private final static CopyOnWriteArrayList list = new CopyOnWriteArrayList(); + + public static void main(String[] args) { + // 这个例子再次证明, + // 多个步骤的操作,不能保证原子性 + // list.size() 获取到的数,再继续用list时,可能已经变了 + // + test(); + } + public static void test(){ + for(int i = 0; i<10000; i++){ + list.add("string" + i); + } + + new Thread(new Runnable() { + @Override + public void run() { + while (true) { + if (list.size() > 0) { // todo : 下一个get操作执行时,size可能已经是0了 + String content = list.get(list.size() - 1); + }else { + break; + } + } + } + }).start(); + + new Thread(new Runnable() { + @Override + public void run() { + while (true) { + if(list.size() <= 0){ + break; + } + list.remove(0); + try { + Thread.sleep(10); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + } + }).start(); + } +} diff --git a/03concurrency/0301/src/main/java/java0/conc0303/collection/LinkedHashMapDemo.java b/03concurrency/0301/src/main/java/java0/conc0303/collection/LinkedHashMapDemo.java new file mode 100644 index 00000000..5786dd7b --- /dev/null +++ b/03concurrency/0301/src/main/java/java0/conc0303/collection/LinkedHashMapDemo.java @@ -0,0 +1,43 @@ +package java0.conc0303.collection; + +import java.util.HashMap; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.Set; + +public class LinkedHashMapDemo { + public static void main(String[] args) { + + // test hash map + System.out.println("=====>1. test hash map"); + Map hashMap = new HashMap(); + hashMap.put("name1", "josan1"); + hashMap.put("name2", "josan2"); + hashMap.put("name3", "josan3"); + Set> set = hashMap.entrySet(); + Iterator> iterator = set.iterator(); + while(iterator.hasNext()) { + Map.Entry entry = iterator.next(); + String key = (String) entry.getKey(); + String value = (String) entry.getValue(); + System.out.println("key:" + key + ",value:" + value); + } + + // test linked hash map + System.out.println("=====>2. test linked hash map"); + Map linkedHashMap = new LinkedHashMap<>(); + linkedHashMap.put("name1", "josan1"); + linkedHashMap.put("name2", "josan2"); + linkedHashMap.put("name3", "josan3"); + Set> set1 = linkedHashMap.entrySet(); + Iterator> iterator1 = set1.iterator(); + while(iterator1.hasNext()) { + Map.Entry entry = iterator1.next(); + String key = (String) entry.getKey(); + String value = (String) entry.getValue(); + System.out.println("key:" + key + ",value:" + value); + } + + } +} diff --git a/03concurrency/0301/src/main/java/java0/conc0303/collection/SyncListDemo.java b/03concurrency/0301/src/main/java/java0/conc0303/collection/SyncListDemo.java new file mode 100644 index 00000000..95e2be28 --- /dev/null +++ b/03concurrency/0301/src/main/java/java0/conc0303/collection/SyncListDemo.java @@ -0,0 +1,47 @@ +package java0.conc0303.collection; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +public class SyncListDemo { + + public static void main(String[] args) { + List list0 = Arrays.asList(1,2,3,4,5,6,7,8,8); + list0.set(8,9); // 可以修改内容,不能变动元素数量 + // list0.add(10) will throw an error + + List list = new ArrayList(); // 正常List,可以操作 + list.addAll(list0); + + List list1 = Collections.synchronizedList(list); + + // 多线程操作 + // to do something + + System.out.println(Arrays.toString(list1.toArray())); + + Collections.shuffle(list1); + + + + System.out.println(Arrays.toString(list1.toArray())); + + + // 假如不再修改 + + List list2 = Collections.unmodifiableList(list1); + + System.out.println(list2.getClass()); + + list2.set(8,10); + + System.out.println(Arrays.toString(list2.toArray())); + + list2.add(11); + + System.out.println(Arrays.toString(list2.toArray())); + } + +} diff --git a/03concurrency/0301/src/main/java/java0/conc0303/collection/TreeMapDemo.java b/03concurrency/0301/src/main/java/java0/conc0303/collection/TreeMapDemo.java new file mode 100644 index 00000000..bb04f20e --- /dev/null +++ b/03concurrency/0301/src/main/java/java0/conc0303/collection/TreeMapDemo.java @@ -0,0 +1,25 @@ +package java0.conc0303.collection; + +import java.util.Comparator; +import java.util.TreeMap; + +public class TreeMapDemo { + + public static void main(String[] args) { + + // + TreeMap map = new TreeMap<>(Comparator.reverseOrder()); + map.put(3, "val"); + map.put(2, "val"); + map.put(1, "val"); + map.put(5, "val"); + map.put(4, "val"); + // {5=val, 4=val, 3=val, 2=val, 1=val} + System.out.println(map); + + TreeMap map1 = new TreeMap<>(Comparator.naturalOrder()); + map1.putAll(map); + System.out.println(map1); + } + +} diff --git a/03concurrency/0301/src/main/java/java0/conc0303/future/CompletableFutureDemo.java b/03concurrency/0301/src/main/java/java0/conc0303/future/CompletableFutureDemo.java new file mode 100644 index 00000000..2a21f4f5 --- /dev/null +++ b/03concurrency/0301/src/main/java/java0/conc0303/future/CompletableFutureDemo.java @@ -0,0 +1,81 @@ +package java0.conc0303.future; + +import java.util.concurrent.CompletableFuture; + +public class CompletableFutureDemo { + + public static void main(String[] args){ + + // 1.变换结果 + System.out.println("=====>1.变换结果"); + String result1 = CompletableFuture.supplyAsync(()->{return "Hello ";}).thenApplyAsync(v -> v + "world").join(); + System.out.println(result1); + + // 2.消费 + CompletableFuture.supplyAsync(()->{return "Hello ";}).thenAccept(v -> { System.out.println("=====>2.消费");System.out.println("consumer: " + v);}); + + // 3.组合 + System.out.println("=====>3.组合"); + String result3 = CompletableFuture.supplyAsync(()->{ + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + return "Hello"; + }).thenCombine(CompletableFuture.supplyAsync(()->{ + try { + Thread.sleep(2000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + return "world"; + }),(s1,s2)->{return s1 + " " + s2;}).join(); + System.out.println("thenCombine:"+result3); + + CompletableFuture.supplyAsync(() -> "Hello, java course.") + .thenApply(String::toUpperCase).thenCompose(s -> CompletableFuture.supplyAsync(s::toLowerCase)).thenAccept(v -> { System.out.println("thenCompose:"+v);}); + + // 4.竞争 + System.out.println("=====>4.竞争"); + String result4 = CompletableFuture.supplyAsync(()->{ + try { + Thread.sleep(100); + } catch (InterruptedException e) { + e.printStackTrace(); + } + return "Hi Boy"; + }).applyToEither(CompletableFuture.supplyAsync(()->{ + try { + Thread.sleep(300); + } catch (InterruptedException e) { + e.printStackTrace(); + } + return "Hi Girl"; + }),(s)->{return s;}).join(); + System.out.println(result4); + + // 5.补偿异常 + System.out.println("=====>5.补偿异常"); + String result5 = CompletableFuture.supplyAsync(()->{ + try { + Thread.sleep(100); + } catch (InterruptedException e) { + e.printStackTrace(); + } + if(true) { + throw new RuntimeException("exception test!"); + } + + return "Hi Boy"; + }).exceptionally(e->{ + System.out.println(e.getMessage()); + return "Hello world!"; + }).join(); + System.out.println(result5); + + + + } + +} diff --git a/03concurrency/0301/src/main/java/java0/conc0303/future/FutureDemo1.java b/03concurrency/0301/src/main/java/java0/conc0303/future/FutureDemo1.java new file mode 100644 index 00000000..14a16383 --- /dev/null +++ b/03concurrency/0301/src/main/java/java0/conc0303/future/FutureDemo1.java @@ -0,0 +1,23 @@ +package java0.conc0303.future; + +import java.util.Random; +import java.util.concurrent.*; + +public class FutureDemo1 { + public static void main(String[] args) { + ExecutorService executor = Executors.newCachedThreadPool(); + Future result = executor.submit(new Callable() { + public Integer call() throws Exception { + return new Random().nextInt(); + } + }); + executor.shutdown(); + try { + System.out.println("result:" + result.get()); + } catch (InterruptedException e) { + e.printStackTrace(); + } catch (ExecutionException e) { + e.printStackTrace(); + } + } +} \ No newline at end of file diff --git a/03concurrency/0301/src/main/java/java0/conc0303/future/FutureTask1.java b/03concurrency/0301/src/main/java/java0/conc0303/future/FutureTask1.java new file mode 100644 index 00000000..69499819 --- /dev/null +++ b/03concurrency/0301/src/main/java/java0/conc0303/future/FutureTask1.java @@ -0,0 +1,35 @@ +package java0.conc0303.future; + +import java.util.Random; +import java.util.concurrent.*; + +public class FutureTask1 { + public static void main(String[] args) { + //第一种方式 + FutureTask task = new FutureTask(new Callable() { + @Override + public Integer call() throws Exception { + return new Random().nextInt(); + } + }); + new Thread(task).start(); + //第二种方方式 +// ExecutorService executor = Executors.newSingleThreadExecutor(); +// FutureTask task = new FutureTask(new Callable() { +// @Override +// public Integer call() throws Exception { +// return new Random().nextInt(); +// } +// }); +// executor.submit(task); + + try { + System.out.println("result: " + task.get()); + } catch (InterruptedException e) { + e.printStackTrace(); + } catch (ExecutionException e) { + e.printStackTrace(); + } + } + +} \ No newline at end of file diff --git a/03concurrency/0301/src/main/java/java0/conc0303/stream/StreamParallelDemo.java b/03concurrency/0301/src/main/java/java0/conc0303/stream/StreamParallelDemo.java new file mode 100644 index 00000000..5b02350b --- /dev/null +++ b/03concurrency/0301/src/main/java/java0/conc0303/stream/StreamParallelDemo.java @@ -0,0 +1,34 @@ +package java0.conc0303.stream; + +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.stream.Collectors; +import java.util.stream.IntStream; + +public class StreamParallelDemo { + public static void main(String[] args) { + List list = new ArrayList<>(); + IntStream.range(1, 10000).forEach(i -> list.add(i)); + BlockingQueue blockingQueue = new LinkedBlockingQueue(10000); + List longList = list.stream().parallel() + .map(i -> i.longValue()) + .sorted() + .collect(Collectors.toList()); +// // 串行,单线程 +// longList.stream().forEach( + // 并行,默认使用CPU * 2个线程 + longList.stream().parallel().forEach( + i -> { + try { + blockingQueue.put(i); + } catch (InterruptedException e) { + e.printStackTrace(); + } + }); + System.out.println("blockingQueue:" + blockingQueue.toString()); + } + + +} diff --git a/03concurrency/0301/src/main/java/java0/conc0303/threadlocal/ThreadLocalDemo.java b/03concurrency/0301/src/main/java/java0/conc0303/threadlocal/ThreadLocalDemo.java new file mode 100644 index 00000000..bbfe35e0 --- /dev/null +++ b/03concurrency/0301/src/main/java/java0/conc0303/threadlocal/ThreadLocalDemo.java @@ -0,0 +1,48 @@ +package java0.conc0303.threadlocal; + +public class ThreadLocalDemo { + + private static ThreadLocal seqNum = new ThreadLocal() { + public Integer initialValue() { + return 0; + } + }; + + public ThreadLocal getThreadLocal() { + return seqNum; + } + + public int getNextNum() { + seqNum.set(seqNum.get() + 1); + return seqNum.get(); + } + + + public static void main(String[] args) { + ThreadLocalDemo threadLocalMain = new ThreadLocalDemo(); + + SnThread client1 = new SnThread(threadLocalMain); + SnThread client2 = new SnThread(threadLocalMain); + SnThread client3 = new SnThread(threadLocalMain); + + client1.start(); + client2.start(); + client3.start(); + } + + + private static class SnThread extends Thread { + private ThreadLocalDemo sn; + + public SnThread(ThreadLocalDemo sn) { + this.sn = sn; + } + + public void run() { + for (int i = 0; i < 3; i++) { + System.out.println("thread[" + Thread.currentThread().getName() + "] ---> sn [" + sn.getNextNum() + "]"); + } + sn.getThreadLocal().remove(); + } + } +} diff --git a/03concurrency/0301/src/main/java/java0/conc0303/tool/CountDownLatchDemo.java b/03concurrency/0301/src/main/java/java0/conc0303/tool/CountDownLatchDemo.java new file mode 100644 index 00000000..b93731be --- /dev/null +++ b/03concurrency/0301/src/main/java/java0/conc0303/tool/CountDownLatchDemo.java @@ -0,0 +1,33 @@ +package java0.conc0303.tool; + +import java.util.concurrent.CountDownLatch; + +public class CountDownLatchDemo { + public static void main(String[] args) throws InterruptedException { + CountDownLatch countDownLatch = new CountDownLatch(5); + for(int i=0;i<5;i++){ + new Thread(new readNum(i,countDownLatch)).start(); + } + countDownLatch.await(); // 注意跟CyclicBarrier不同,这里在主线程await + System.out.println("==>各个子线程执行结束。。。。"); + System.out.println("==>主线程执行结束。。。。"); + } + + static class readNum implements Runnable{ + private int id; + private CountDownLatch latch; + public readNum(int id,CountDownLatch latch){ + this.id = id; + this.latch = latch; + } + @Override + public void run() { + 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/CountDownLatchDemo2.java b/03concurrency/0301/src/main/java/java0/conc0303/tool/CountDownLatchDemo2.java new file mode 100644 index 00000000..eff0ba40 --- /dev/null +++ b/03concurrency/0301/src/main/java/java0/conc0303/tool/CountDownLatchDemo2.java @@ -0,0 +1,40 @@ +package java0.conc0303.tool; + + +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + +public class CountDownLatchDemo2 { + + private final static int threadCount = 200; + + public static void main(String[] args) throws Exception { + + ExecutorService exec = Executors.newCachedThreadPool(); + + final CountDownLatch countDownLatch = new CountDownLatch(threadCount); + + for (int i = 0; i < threadCount; i++) { + final int threadNum = i; + exec.execute(() -> { + try { + test(threadNum); + } catch (Exception e) { + e.printStackTrace(); + } finally { + countDownLatch.countDown(); + } + }); + } + countDownLatch.await(); + System.out.println("==>所有程序员完成任务,项目顺利上线!"); + exec.shutdown(); + } + + private static void test(int threadNum) throws Exception { + Thread.sleep(100); + System.out.println(String.format("程序员[%d]完成任务。。。", threadNum)); + Thread.sleep(100); + } +} \ 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 new file mode 100644 index 00000000..bc8417d7 --- /dev/null +++ b/03concurrency/0301/src/main/java/java0/conc0303/tool/CyclicBarrierDemo.java @@ -0,0 +1,48 @@ +package java0.conc0303.tool; + +import java.util.concurrent.CyclicBarrier; + +public class CyclicBarrierDemo { + public static void main(String[] args) throws InterruptedException { + CyclicBarrier cyclicBarrier = new CyclicBarrier(5, new Runnable() { + @Override + public void run() { + System.out.println("回调>>"+Thread.currentThread().getName()); + System.out.println("回调>>线程组执行结束"); + } + }); + for (int i = 0; i < 5; i++) { + new Thread(new readNum(i,cyclicBarrier)).start(); + } + + System.out.println("==>各个子线程执行结束。。。。"); + System.out.println("==>主线程执行结束。。。。"); + + //CyclicBarrier 可以重复利用, + // 这个是CountDownLatch做不到的 +// for (int i = 11; i < 16; i++) { +// new Thread(new readNum(i,cyclicBarrier)).start(); +// } + } + static class readNum implements Runnable{ + private int id; + private CyclicBarrier cyc; + public readNum(int id,CyclicBarrier cyc){ + this.id = id; + this.cyc = cyc; + } + @Override + public void run() { + synchronized (this){ + System.out.println("id:"+id+","+Thread.currentThread().getName()); + try { + //cyc.await(); + System.out.println("线程组任务" + id + "结束,其他任务继续"); + 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/CyclicBarrierDemo2.java b/03concurrency/0301/src/main/java/java0/conc0303/tool/CyclicBarrierDemo2.java new file mode 100644 index 00000000..9c83bc26 --- /dev/null +++ b/03concurrency/0301/src/main/java/java0/conc0303/tool/CyclicBarrierDemo2.java @@ -0,0 +1,49 @@ +package java0.conc0303.tool; + +import java.util.concurrent.BrokenBarrierException; +import java.util.concurrent.CyclicBarrier; + +public class CyclicBarrierDemo2 { + public static void main(String[] args) { + int N = 4; + CyclicBarrier barrier = new CyclicBarrier(N); + + for(int i=0;i { + try { + semaphore.acquire(3); // 获取全部许可,退化成串行执行 + test(threadNum); + semaphore.release(3); // 释放多个许可 + } catch (Exception e) { + e.printStackTrace(); + } + }); + } + exec.shutdown(); + } + + private static void test(int threadNum) throws Exception { + System.out.println("id:"+threadNum+","+Thread.currentThread().getName()); + Thread.sleep(1000); + } + } diff --git a/03concurrency/0301/src/main/java/java0/conc0303/tool/SemaphoreDemo3.java b/03concurrency/0301/src/main/java/java0/conc0303/tool/SemaphoreDemo3.java new file mode 100644 index 00000000..3a02dc78 --- /dev/null +++ b/03concurrency/0301/src/main/java/java0/conc0303/tool/SemaphoreDemo3.java @@ -0,0 +1,115 @@ + +package java0.conc0303.tool; + +import java.util.concurrent.Semaphore; + +public class SemaphoreDemo3 { + + public static void main(String[] args) { + // 启动线程 + for (int i = 0; i <= 10; i++) { + // 生产者 + new Thread(new Producer()).start(); + // 消费者 + new Thread(new Consumer()).start(); + } + } + + + // 仓库 + static Warehouse buffer = new Warehouse(); + + static class Producer implements Runnable { + + static int num = 1; + + @Override + public void run() { + int n = num++; + while (true) { + try { + buffer.put(n); + System.out.println(">" + n); + // 速度较快。休息10毫秒 + Thread.sleep(10); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + } + } + + + static class Consumer implements Runnable { + @Override + public void run() { + while (true) { + try { + System.out.println("<" + buffer.take()); + // 速度较慢,休息1000毫秒 + Thread.sleep(1000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + } + } + + + static class Warehouse { + // 非满锁 + final Semaphore notFull = new Semaphore(10); + // 非空锁 + final Semaphore notEmpty = new Semaphore(0); + // 核心锁 + final Semaphore mutex = new Semaphore(1); + // 库存容量 + final Object[] items = new Object[10]; + int putptr, takeptr, count; + + + /** + * 放库存 + * + * @param obj + * @throws InterruptedException + */ + public void put(Object obj) throws InterruptedException { + notFull.acquire(); + mutex.acquire(); + items[putptr] = obj; + try { + if (++putptr == items.length) { + putptr = 0; + ++count; + } + } finally { + mutex.release(); + notEmpty.release(); + } + } + + /** + * 取库存 + * + * @return + * @throws InterruptedException + */ + public Object take() throws InterruptedException { + notEmpty.acquire(); + mutex.acquire(); + Object obj = items[takeptr]; + try { + if (++takeptr == items.length) { + takeptr = 0; + --count; + } + return obj; + } finally { + mutex.release(); + notFull.release(); + } + } + } + +} diff --git a/homework2.0.md b/homework2.0.md new file mode 100644 index 00000000..cc9ac48a --- /dev/null +++ b/homework2.0.md @@ -0,0 +1,39 @@ +以下是针对目前已经符合P6+/P7水平的同学,并且有时间可以挑战一下自己的。能做出来90分以上,直接联系我。 + +### 1. JVM附加作业 + +从Classloader到模块化,动态加载的插件机制。 + +1. 10-使用自定义Classloader机制,实现xlass的加载 +2. 20-实现xlass打包的xar(类似class文件打包的jar)的加载 +3. 30-基于自定义Classloader实现类的动态加载和卸载 +4. 30-基于自定义Classloader实现模块化机制 +5. 30-使用xar作为模块,实现xar动态加载和卸载 + +### 2. NIO附加作业 + +实现一个http 文件服务器和一个ftp文件服务器。 +1. 10-实现文件列表展示 +2. 20-实现文件上传下载 +3. 30-支持断点续传 +4. 30-实现多线程文件上传下载 +5. 30-实现爬虫爬取前面实现的服务器上所有文件 + +### 3. 并发集合类 + +#### 3.1-侧重集合: + +1. 10-基于基本类型和数组,实现ArrayList/LinkedList,支持自动扩容和迭代器 +2. 20-基于基本类型和数组和List,HashMap/LinkedHashMap功能,处理hash冲突和扩容 +3. 30-考虑List和Map的并发安全问题,基于读写锁改进安全问题 +4. 30-考虑List和Map的并发安全问题,基于AQS改进安全问题 +5. 30-编写测试代码比较它们与java-util/JUC集合类的性能和并发安全性 + +#### 3.2-侧重应用: + +1. 10-根据课程提供的场景,实现一个订单处理Service,模拟处理100万订单 +2. 20-使用多线程方法优化订单处理,对比处理性能 +3. 30-使用并发工具和集合类改进订单Service,对比处理性能 +4. 30-使用分布式集群+分库分表方式处理拆分订单,对比处理性能 +5. 30-使用读写分离和分布式缓存优化订单的读性能 +