├── .idea ├── .gitignore ├── smartfox_info.xml ├── vcs.xml ├── misc.xml ├── compiler.xml ├── inspectionProfiles │ └── Project_Default.xml └── uiDesigner.xml ├── src └── main │ └── java │ └── com │ └── chao │ ├── concurrency_basic │ ├── chapter5 │ │ ├── note.txt │ │ ├── ThreadJoin.java │ │ ├── ThreadJoin2.java │ │ └── ThreadJoin3.java │ ├── chapter4 │ │ ├── note.txt │ │ ├── DaemonThread.java │ │ ├── DaemonThread2.java │ │ └── ThreadSimpleAPI.java │ ├── chapter13_SIMPLE_THREAD_POOL │ │ ├── note.txt │ │ ├── Test.java │ │ ├── activeThreadTest.java │ │ ├── Test2.java │ │ ├── Test3.java │ │ ├── SimpleThreadPool.java │ │ ├── SimpleThreadPool2.java │ │ └── SimpleThreadPool3.java │ ├── chapter2 │ │ ├── tax │ │ │ ├── CalculatorStrategy.java │ │ │ ├── SimpleCalculatorStrategy.java │ │ │ ├── TaxCalculatorMain.java │ │ │ └── TaxCalculator.java │ │ ├── bank1 │ │ │ ├── Bank1.java │ │ │ └── TicketWindowThread.java │ │ └── bank2 │ │ │ ├── Bank2.java │ │ │ └── TicketWindowRunnable.java │ ├── chapter1 │ │ ├── note.txt │ │ ├── TemplateMethod.java │ │ └── TryConcurrency.java │ ├── chapter7 │ │ ├── Bank2.java │ │ ├── Bank3.java │ │ ├── TicketWindowRunnable.java │ │ ├── SynchronizedTest.java │ │ ├── SynchronizedThis.java │ │ ├── SynchronizedRunnable.java │ │ └── note.txt │ ├── chapter10_CUSTOM_LOCK │ │ ├── Lock.java │ │ ├── LockTest.java │ │ └── BooleanLock.java │ ├── chapter8 │ │ ├── OtherService.java │ │ ├── DeadLock.java │ │ └── DeadLockTest.java │ ├── chapter12 │ │ ├── note.txt │ │ ├── ThreadGroupAPI.java │ │ └── ThreadGroupCreate.java │ ├── chapter6 │ │ ├── ThreadCloseGraceful2.java │ │ ├── ThreadCloseGraceful.java │ │ ├── ThreadCloseForce.java │ │ ├── note.txt │ │ ├── ThreadInterrupt.java │ │ └── ThreadService.java │ ├── chapter11 │ │ ├── ThreadException.java │ │ └── CaptureThreadRuntimeException.java │ ├── chapter3 │ │ ├── note.txt │ │ ├── CreateThread.java │ │ ├── CreateThread2.java │ │ └── CreateThread3.java │ └── chapter9 │ │ ├── note.txt │ │ ├── ProduceConsumerVersion1 │ │ └── ProduceConsumer1.java │ │ ├── differenceOfWaitAndSleep │ │ └── DifferenceOfWaitAndSleep.java │ │ ├── ProduceConsumerVersion2 │ │ └── ProduceConsumer2.java │ │ ├── ProduceConsumerVersion3 │ │ └── ProduceConsumer3.java │ │ └── CaptureService.java │ ├── design_pattern │ ├── chapter10 │ │ ├── note.txt │ │ └── ThreadLocalTest.java │ ├── chapter8_FUTURE │ │ ├── Future.java │ │ ├── FutureTask.java │ │ ├── FutureService.java │ │ ├── AsynFuture.java │ │ ├── note.txt │ │ └── FutureTest.java │ ├── chapter18_ACTIVE_OBJECT_important │ │ ├── Result.java │ │ ├── Avtive Object.png │ │ ├── ActiveObject.java │ │ ├── MethodRequest.java │ │ ├── RealResult.java │ │ ├── Client.java │ │ ├── DisplayStringRequest.java │ │ ├── ActiveObjectFactory.java │ │ ├── MakeStringRequest.java │ │ ├── FutureResult.java │ │ ├── DisplayClientThread.java │ │ ├── SchedulerThread.java │ │ ├── Servant.java │ │ ├── ActiveObjectProxy.java │ │ ├── MakerClientThread.java │ │ └── ActivationQueue.java │ ├── chapter9 │ │ ├── Request.java │ │ ├── RequestTest.java │ │ ├── RequestClient.java │ │ ├── RequestQueue.java │ │ └── RequestServer.java │ ├── chapter13_PRODUCER_CONSUMER │ │ ├── Message.java │ │ ├── ProducerAndConsumerClient.java │ │ ├── ConsumerThread.java │ │ ├── ProducerThread.java │ │ └── MessageQueue.java │ ├── chapter17_WORKER_THREAD │ │ ├── Request.java │ │ ├── WorkerThreadTest.java │ │ ├── WorkerTread.java │ │ ├── TransportThread.java │ │ └── Channel.java │ ├── chapter15_THREAD_PER_MESSAGE │ │ ├── Message.java │ │ ├── MessageRequestClient.java │ │ └── MessageHandle.java │ ├── chapter4_OBSERVER │ │ ├── multithread_Observer_to_moniror_the_Thread_lifecycle │ │ │ ├── LifeCycleListener.java │ │ │ ├── LifeCycleClient.java │ │ │ ├── ObservableRunnable.java │ │ │ └── ObserverLifeCycleListener.java │ │ └── normal_observer_pattern │ │ │ ├── Observer.java │ │ │ ├── BinaryObserver.java │ │ │ ├── OctalObserver.java │ │ │ ├── ObserverClient.java │ │ │ └── Subject.java │ ├── chapter16_TWO_PHASE_TERMINATE │ │ ├── test │ │ │ ├── ClientAndService.java │ │ │ ├── ClientHandle.java │ │ │ └── AppServer.java │ │ └── custom_test │ │ │ ├── TerminationRequester.java │ │ │ └── Terminator.java │ ├── chapter1 │ │ ├── SingletonObject1.java │ │ ├── SingletonObject2.java │ │ ├── SingletonObject6.java │ │ ├── SingletonObject3.java │ │ ├── SingletonObject7.java │ │ ├── SingletonObject5.java │ │ └── SingletonObject4.java │ ├── chapter7_IMMUTABLE_DESIGN_PATTERN │ │ ├── ImmutableClient.java │ │ ├── UserPersonThread.java │ │ ├── Person.java │ │ └── note.txt │ ├── chapter11 │ │ ├── Context.java │ │ ├── ContextClient.java │ │ ├── QueryFromDBAction.java │ │ ├── ExecutionTask.java │ │ ├── QueryFromHttp.java │ │ └── ActionContext.java │ ├── chapter5_SINGLE_THREADED_EXECUTION │ │ ├── Client.java │ │ ├── User.java │ │ └── Gate.java │ ├── chapter6_READ_WRITE_LOCK │ │ ├── note.txt │ │ ├── ReadWriteLockTest.java │ │ ├── ReadWorker.java │ │ ├── WriteWorker.java │ │ ├── SharedData.java │ │ └── ReadWriteLock.java │ ├── chapter14_CUSTOM_COUNT_DOWN_LATCH │ │ ├── CountDown.java │ │ ├── CustomCountDown.java │ │ └── JDKCountDown.java │ ├── chapter12_BALKING │ │ └── BalkingData.java │ ├── chapter3 │ │ ├── VolatileTest.java │ │ └── note.txt │ └── chapter2 │ │ └── WaitSet.java │ └── _self │ ├── self_lock │ ├── Test.java │ └── Mutex.java │ ├── thread_pool │ ├── ThreadPool.java │ ├── Test3.java │ └── DefaultThreadPool.java │ ├── connection_pool │ ├── ConnectionDriver.java │ ├── ConnectionPool.java │ └── ConnectionPoolTest.java │ ├── semaphore │ └── SemaphoreTest.java │ ├── exchanger │ └── ExchangerTest.java │ ├── twins_lock │ ├── TestTwinsLock.java │ └── TwinsLock.java │ ├── cyclicBarrier │ └── BankWaterService.java │ ├── condition_await_signal │ └── BoundedQueue.java │ └── readwrite_lock │ └── TestReadWriteLock.java └── pom.xml /.idea/.gitignore: -------------------------------------------------------------------------------- 1 | # Default ignored files 2 | /workspace.xml -------------------------------------------------------------------------------- /src/main/java/com/chao/concurrency_basic/chapter5/note.txt: -------------------------------------------------------------------------------- 1 | 1.join()方法使当前线程等待线程结束后再继续执行当前线程的工作 2 | 3 | 2.join()方法可以设置最多等待的时间 4 | 5 | 3.join()方法由需要被等待的线程来调用 -------------------------------------------------------------------------------- /src/main/java/com/chao/design_pattern/chapter10/note.txt: -------------------------------------------------------------------------------- 1 | ThreadLocal:这个类提供线程局部变量,这些变量与正常的变量不同点在于,每个线程使用set()和get()方法设置和访问的变量都是属于它这个线程的初始化值的副本,ThreadLocal实例通常是希望将线程与线程相关联的类的私有静态变量联系起来所使用的(例如ThreadID)。 -------------------------------------------------------------------------------- /src/main/java/com/chao/concurrency_basic/chapter4/note.txt: -------------------------------------------------------------------------------- 1 | 1.通过setDaemon()方法参数设置为true,将线程变为守护线程,并且此方法要在start()方法之前调用,否则会报异常 2 | 3 | 2.守护线程随着所有活动的的线程销毁而被销毁 4 | 5 | 3.守护线程一般作为辅助性程序使用,避免某些非主要功能一直是活动线程,导致JVM不能退出 -------------------------------------------------------------------------------- /src/main/java/com/chao/design_pattern/chapter8_FUTURE/Future.java: -------------------------------------------------------------------------------- 1 | package com.chao.design_pattern.chapter8_FUTURE; 2 | 3 | public interface Future { 4 | T get() throws InterruptedException; 5 | } 6 | -------------------------------------------------------------------------------- /src/main/java/com/chao/concurrency_basic/chapter13_SIMPLE_THREAD_POOL/note.txt: -------------------------------------------------------------------------------- 1 | 1.线程池一些概念:任务队列;拒绝策略(抛出异常,直接丢弃,阻塞,临时队列);初始化大小;活动线程;线程池最大线程数 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /src/main/java/com/chao/design_pattern/chapter18_ACTIVE_OBJECT_important/Result.java: -------------------------------------------------------------------------------- 1 | package com.chao.design_pattern.chapter18_ACTIVE_OBJECT_important; 2 | 3 | public interface Result { 4 | Object getResultValue(); 5 | } 6 | -------------------------------------------------------------------------------- /.idea/smartfox_info.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | -------------------------------------------------------------------------------- /src/main/java/com/chao/design_pattern/chapter18_ACTIVE_OBJECT_important/Avtive Object.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chaos-woo/Multithreading-study/HEAD/src/main/java/com/chao/design_pattern/chapter18_ACTIVE_OBJECT_important/Avtive Object.png -------------------------------------------------------------------------------- /src/main/java/com/chao/design_pattern/chapter8_FUTURE/FutureTask.java: -------------------------------------------------------------------------------- 1 | package com.chao.design_pattern.chapter8_FUTURE; 2 | 3 | /** 4 | * 真正执行任务的接口 5 | * @param 6 | */ 7 | public interface FutureTask { 8 | T call(); 9 | } 10 | -------------------------------------------------------------------------------- /src/main/java/com/chao/concurrency_basic/chapter2/tax/CalculatorStrategy.java: -------------------------------------------------------------------------------- 1 | package com.chao.concurrency_basic.chapter2.tax; 2 | 3 | @FunctionalInterface 4 | public interface CalculatorStrategy { 5 | double calculate(double salary, double bonus); 6 | } 7 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /src/main/java/com/chao/_self/self_lock/Test.java: -------------------------------------------------------------------------------- 1 | package com.chao._self.self_lock; 2 | 3 | /** 4 | * Description: 5 | * 6 | * @author W.Chao 7 | * @date 2019/8/22 15:09 8 | **/ 9 | public class Test { 10 | 11 | public static void main(String[] args) { 12 | 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/com/chao/design_pattern/chapter9/Request.java: -------------------------------------------------------------------------------- 1 | package com.chao.design_pattern.chapter9; 2 | 3 | public class Request { 4 | private final String value; 5 | 6 | public Request(String value) { 7 | this.value = value; 8 | } 9 | 10 | public String getValue() { 11 | return value; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/main/java/com/chao/design_pattern/chapter13_PRODUCER_CONSUMER/Message.java: -------------------------------------------------------------------------------- 1 | package com.chao.design_pattern.chapter13_PRODUCER_CONSUMER; 2 | 3 | public class Message { 4 | private String msg; 5 | 6 | public Message(String msg) { 7 | this.msg = msg; 8 | } 9 | 10 | public String getMsg() { 11 | return msg; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/main/java/com/chao/design_pattern/chapter17_WORKER_THREAD/Request.java: -------------------------------------------------------------------------------- 1 | package com.chao.design_pattern.chapter17_WORKER_THREAD; 2 | 3 | public class Request { 4 | private String msg; 5 | 6 | 7 | public Request(String msg) { 8 | this.msg = msg; 9 | } 10 | 11 | public String getMsg() { 12 | return msg; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/com/chao/design_pattern/chapter15_THREAD_PER_MESSAGE/Message.java: -------------------------------------------------------------------------------- 1 | package com.chao.design_pattern.chapter15_THREAD_PER_MESSAGE; 2 | 3 | public class Message { 4 | private String msg; 5 | 6 | public Message(String msg) { 7 | this.msg = msg; 8 | } 9 | 10 | public String getMsg() { 11 | return msg; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/main/java/com/chao/design_pattern/chapter4_OBSERVER/multithread_Observer_to_moniror_the_Thread_lifecycle/LifeCycleListener.java: -------------------------------------------------------------------------------- 1 | package com.chao.design_pattern.chapter4_OBSERVER.multithread_Observer_to_moniror_the_Thread_lifecycle; 2 | 3 | public interface LifeCycleListener { 4 | void onEvent(ObservableRunnable.RunnableEvent event); 5 | } 6 | -------------------------------------------------------------------------------- /src/main/java/com/chao/concurrency_basic/chapter1/note.txt: -------------------------------------------------------------------------------- 1 | 1.Java应用程序的main函数是一个线程,是被JVM启动的时候调用,线程的名字叫main 2 | 3 | 2.实现一个线程,必须创建Thread实例,覆盖run()方法,并且调用start()方法,调用start()方法时,会调用一个native方法start0(),而start0()方法会调用覆盖的run()方法 4 | 5 | 3.当JVM启动后,实际上有多个线程,但是至少有一个非守护线程 6 | 7 | 4.当你调用一个线程start()方法的时候,此时至少有两个线程,一个是你调用的线程,还有一个是执行run()方法的线程 8 | 9 | 5.线程的生命周期分为new,runnable,running,block,terminate -------------------------------------------------------------------------------- /src/main/java/com/chao/design_pattern/chapter4_OBSERVER/normal_observer_pattern/Observer.java: -------------------------------------------------------------------------------- 1 | package com.chao.design_pattern.chapter4_OBSERVER.normal_observer_pattern; 2 | 3 | public abstract class Observer { 4 | protected Subject subject; 5 | 6 | public Observer(Subject subject){ 7 | this.subject = subject; 8 | subject.attach(this); 9 | } 10 | 11 | public abstract void update(); 12 | 13 | } 14 | -------------------------------------------------------------------------------- /src/main/java/com/chao/design_pattern/chapter16_TWO_PHASE_TERMINATE/test/ClientAndService.java: -------------------------------------------------------------------------------- 1 | package com.chao.design_pattern.chapter16_TWO_PHASE_TERMINATE.test; 2 | 3 | public class ClientAndService { 4 | public static void main(String[] args) throws InterruptedException { 5 | AppServer server = new AppServer(); 6 | server.start(); 7 | 8 | Thread.sleep(50_000); 9 | server.shutdown(); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/main/java/com/chao/design_pattern/chapter1/SingletonObject1.java: -------------------------------------------------------------------------------- 1 | package com.chao.design_pattern.chapter1; 2 | 3 | /** 4 | * 不能够懒加载,因为类加载时instance同时被加载到内存 5 | */ 6 | public class SingletonObject1 { 7 | private static final SingletonObject1 instance = new SingletonObject1(); 8 | 9 | private SingletonObject1(){} 10 | 11 | public static SingletonObject1 getInstance(){ 12 | return instance; 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/com/chao/_self/thread_pool/ThreadPool.java: -------------------------------------------------------------------------------- 1 | package com.chao._self.thread_pool; 2 | 3 | /** 4 | * Description: 5 | * 6 | * @author W.Chao 7 | * @date 2019/8/21 19:00 8 | **/ 9 | public interface ThreadPool{ 10 | // 执行job任务 11 | void execute(Job job); 12 | // 关闭线程池 13 | void shutdown(); 14 | // 增加工作线程 15 | void addWorker(int num); 16 | // 减小工作线程 17 | void removeWorker(int num); 18 | } 19 | -------------------------------------------------------------------------------- /src/main/java/com/chao/design_pattern/chapter18_ACTIVE_OBJECT_important/ActiveObject.java: -------------------------------------------------------------------------------- 1 | package com.chao.design_pattern.chapter18_ACTIVE_OBJECT_important; 2 | 3 | /** 4 | * 主动对象模式 5 | * 常用应用场景:一般的异步方法调用只能调用一个方法 6 | * 使用Active Object可以调用多个方法,即一个方法执行之后,还可以执行其他方法 7 | * 而不会像一般异步方法在一个方法体中调用其他方法 8 | */ 9 | public interface ActiveObject { 10 | Result makeString(int count, char fillChar); 11 | void displayString(String text); 12 | } 13 | -------------------------------------------------------------------------------- /src/main/java/com/chao/design_pattern/chapter4_OBSERVER/multithread_Observer_to_moniror_the_Thread_lifecycle/LifeCycleClient.java: -------------------------------------------------------------------------------- 1 | package com.chao.design_pattern.chapter4_OBSERVER.multithread_Observer_to_moniror_the_Thread_lifecycle; 2 | 3 | import java.util.Arrays; 4 | 5 | public class LifeCycleClient { 6 | public static void main(String[] args) { 7 | new ObserverLifeCycleListener().concurrentQuery(Arrays.asList("1","2","3")); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/main/java/com/chao/concurrency_basic/chapter2/bank1/Bank1.java: -------------------------------------------------------------------------------- 1 | package com.chao.concurrency_basic.chapter2.bank1; 2 | 3 | public class Bank1 { 4 | public static void main(String[] args) { 5 | TicketWindowThread t1 = new TicketWindowThread("1号柜台"); 6 | TicketWindowThread t2 = new TicketWindowThread("2号柜台"); 7 | TicketWindowThread t3 = new TicketWindowThread("3号柜台"); 8 | 9 | t1.start(); 10 | t2.start(); 11 | t3.start(); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/main/java/com/chao/concurrency_basic/chapter2/tax/SimpleCalculatorStrategy.java: -------------------------------------------------------------------------------- 1 | package com.chao.concurrency_basic.chapter2.tax; 2 | 3 | public class SimpleCalculatorStrategy implements CalculatorStrategy { 4 | 5 | private final static double SALARY_RATE = 0.1; 6 | private final static double BONUS_RATE = 0.15; 7 | 8 | public double calculate(double salary, double bonus) { 9 | return salary * SALARY_RATE + bonus * BONUS_RATE; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/main/java/com/chao/design_pattern/chapter9/RequestTest.java: -------------------------------------------------------------------------------- 1 | package com.chao.design_pattern.chapter9; 2 | 3 | public class RequestTest { 4 | public static void main(String[] args) throws InterruptedException { 5 | RequestQueue queue = new RequestQueue(); 6 | new RequestClient(queue, "leo").start(); 7 | RequestServer server = new RequestServer(queue); 8 | server.start(); 9 | 10 | Thread.sleep(10_000); 11 | server.close(); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/main/java/com/chao/design_pattern/chapter4_OBSERVER/normal_observer_pattern/BinaryObserver.java: -------------------------------------------------------------------------------- 1 | package com.chao.design_pattern.chapter4_OBSERVER.normal_observer_pattern; 2 | 3 | public class BinaryObserver extends Observer { 4 | 5 | public BinaryObserver(Subject subject){ 6 | super(subject); 7 | } 8 | 9 | @Override 10 | public void update() { 11 | System.out.println("Binary Observer: " + Integer.toBinaryString(subject.getStatus())); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/main/java/com/chao/design_pattern/chapter4_OBSERVER/normal_observer_pattern/OctalObserver.java: -------------------------------------------------------------------------------- 1 | package com.chao.design_pattern.chapter4_OBSERVER.normal_observer_pattern; 2 | 3 | public class OctalObserver extends Observer { 4 | 5 | public OctalObserver(Subject subject){ 6 | super(subject); 7 | } 8 | 9 | @Override 10 | public void update() { 11 | System.out.println("Octonary Observer: " + Integer.toOctalString(subject.getStatus())); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/main/java/com/chao/design_pattern/chapter7_IMMUTABLE_DESIGN_PATTERN/ImmutableClient.java: -------------------------------------------------------------------------------- 1 | package com.chao.design_pattern.chapter7_IMMUTABLE_DESIGN_PATTERN; 2 | 3 | import java.util.Collections; 4 | import java.util.stream.IntStream; 5 | 6 | public class ImmutableClient { 7 | 8 | public static void main(String[] args) { 9 | Person person = new Person("leo", "SNH"); 10 | IntStream.range(0, 5).forEach(i -> new UserPersonThread(person).start()); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/main/java/com/chao/concurrency_basic/chapter7/Bank2.java: -------------------------------------------------------------------------------- 1 | package com.chao.concurrency_basic.chapter7; 2 | 3 | public class Bank2 { 4 | public static void main(String[] args) { 5 | final TicketWindowRunnable ticketWindow = new TicketWindowRunnable(); 6 | Thread t1 = new Thread(ticketWindow,"1号窗口"); 7 | Thread t2 = new Thread(ticketWindow,"2号窗口"); 8 | Thread t3 = new Thread(ticketWindow,"3号窗口"); 9 | 10 | t1.start(); 11 | t2.start(); 12 | t3.start(); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/com/chao/concurrency_basic/chapter7/Bank3.java: -------------------------------------------------------------------------------- 1 | package com.chao.concurrency_basic.chapter7; 2 | 3 | public class Bank3 { 4 | public static void main(String[] args) { 5 | final SynchronizedRunnable ticketWindow = new SynchronizedRunnable(); 6 | Thread t1 = new Thread(ticketWindow,"1号窗口"); 7 | Thread t2 = new Thread(ticketWindow,"2号窗口"); 8 | Thread t3 = new Thread(ticketWindow,"3号窗口"); 9 | 10 | t1.start(); 11 | t2.start(); 12 | t3.start(); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/com/chao/design_pattern/chapter1/SingletonObject2.java: -------------------------------------------------------------------------------- 1 | package com.chao.design_pattern.chapter1; 2 | 3 | /** 4 | * 多线程情况下可能会出现不止一个实例 5 | */ 6 | 7 | public class SingletonObject2 { 8 | 9 | private static SingletonObject2 instance; 10 | 11 | private SingletonObject2(){} 12 | 13 | public static SingletonObject2 getInstance(){ 14 | if(null == instance){ 15 | instance = new SingletonObject2(); 16 | } 17 | return SingletonObject2.instance; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/com/chao/concurrency_basic/chapter2/bank2/Bank2.java: -------------------------------------------------------------------------------- 1 | package com.chao.concurrency_basic.chapter2.bank2; 2 | 3 | public class Bank2 { 4 | public static void main(String[] args) { 5 | final TicketWindowRunnable ticketWindow = new TicketWindowRunnable(); 6 | Thread t1 = new Thread(ticketWindow,"1号窗口"); 7 | Thread t2 = new Thread(ticketWindow,"2号窗口"); 8 | Thread t3 = new Thread(ticketWindow,"3号窗口"); 9 | 10 | t1.start(); 11 | t2.start(); 12 | t3.start(); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/com/chao/design_pattern/chapter1/SingletonObject6.java: -------------------------------------------------------------------------------- 1 | package com.chao.design_pattern.chapter1; 2 | 3 | 4 | /** 5 | * 静态内部类中的静态变量Instance在类加载初始化阶段就已经创建好了 6 | */ 7 | public class SingletonObject6 { 8 | private SingletonObject6(){} 9 | 10 | private static class InstanceHolder{ 11 | private static final SingletonObject6 Instance = new SingletonObject6(); 12 | } 13 | 14 | public static SingletonObject6 getInstance(){ 15 | return InstanceHolder.Instance; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/com/chao/design_pattern/chapter11/Context.java: -------------------------------------------------------------------------------- 1 | package com.chao.design_pattern.chapter11; 2 | 3 | public class Context { 4 | private String name; 5 | private String cardId; 6 | 7 | public String getName() { 8 | return name; 9 | } 10 | 11 | public void setName(String name) { 12 | this.name = name; 13 | } 14 | 15 | public String getCardId() { 16 | return cardId; 17 | } 18 | 19 | public void setCardId(String cardId) { 20 | this.cardId = cardId; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/com/chao/design_pattern/chapter17_WORKER_THREAD/WorkerThreadTest.java: -------------------------------------------------------------------------------- 1 | package com.chao.design_pattern.chapter17_WORKER_THREAD; 2 | 3 | public class WorkerThreadTest { 4 | public static void main(String[] args) { 5 | Channel channel = new Channel(5); 6 | // 隐藏了工作线程的显示创建和运行 7 | channel.startWork(); 8 | 9 | new TransportThread("leo", channel).start(); 10 | new TransportThread("alex", channel).start(); 11 | new TransportThread("papa", channel).start(); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/main/java/com/chao/design_pattern/chapter5_SINGLE_THREADED_EXECUTION/Client.java: -------------------------------------------------------------------------------- 1 | package com.chao.design_pattern.chapter5_SINGLE_THREADED_EXECUTION; 2 | 3 | public class Client { 4 | public static void main(String[] args) { 5 | Gate gate = new Gate(); 6 | User bj = new User(gate, "Beijing", "Beijing"); 7 | User sh = new User(gate, "Shanghai", "Shanghai"); 8 | User gz = new User(gate, "Guangzhou", "Guangzhou"); 9 | 10 | bj.start(); 11 | sh.start(); 12 | gz.start(); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/com/chao/design_pattern/chapter18_ACTIVE_OBJECT_important/MethodRequest.java: -------------------------------------------------------------------------------- 1 | package com.chao.design_pattern.chapter18_ACTIVE_OBJECT_important; 2 | 3 | public abstract class MethodRequest { 4 | 5 | protected final Servant servant; 6 | protected final FutureResult futureResult; 7 | 8 | protected MethodRequest(Servant servant, FutureResult futureResult) { 9 | this.servant = servant; 10 | this.futureResult = futureResult; 11 | } 12 | public abstract void execute(); 13 | 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/com/chao/design_pattern/chapter8_FUTURE/FutureService.java: -------------------------------------------------------------------------------- 1 | package com.chao.design_pattern.chapter8_FUTURE; 2 | 3 | public class FutureService { 4 | public Future submit(final FutureTask task){ 5 | AsynFuture asynFuture = new AsynFuture<>(); 6 | new Thread(()->{ 7 | // 执行给定的任务 8 | T result = task.call(); 9 | // 将任务的结果放入asynFuture中 10 | asynFuture.done(result); 11 | }).start(); 12 | // 使用另一个线程执行任务,可以立即返回Future 13 | return asynFuture; 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/com/chao/design_pattern/chapter18_ACTIVE_OBJECT_important/RealResult.java: -------------------------------------------------------------------------------- 1 | package com.chao.design_pattern.chapter18_ACTIVE_OBJECT_important; 2 | 3 | /** 4 | * 真正的结果对象,放置于FutureResult对象中, 5 | * 等待被获取结果值 6 | */ 7 | public class RealResult implements Result { 8 | 9 | private final Object resultValue; 10 | 11 | public RealResult(final Object resultValue){ 12 | this.resultValue = resultValue; 13 | } 14 | 15 | @Override 16 | public Object getResultValue() { 17 | return resultValue; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/com/chao/concurrency_basic/chapter2/bank1/TicketWindowThread.java: -------------------------------------------------------------------------------- 1 | package com.chao.concurrency_basic.chapter2.bank1; 2 | 3 | public class TicketWindowThread extends Thread{ 4 | 5 | private final String name; 6 | private static final int MAX = 1000; 7 | private static int index = 1; 8 | 9 | public TicketWindowThread(String name) { 10 | this.name = name; 11 | } 12 | 13 | @Override 14 | public void run() { 15 | while (index <= MAX){ 16 | System.out.println(name + "当前的号码是:" + (index++)); 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/com/chao/design_pattern/chapter7_IMMUTABLE_DESIGN_PATTERN/UserPersonThread.java: -------------------------------------------------------------------------------- 1 | package com.chao.design_pattern.chapter7_IMMUTABLE_DESIGN_PATTERN; 2 | 3 | public class UserPersonThread extends Thread { 4 | private Person person; 5 | 6 | public UserPersonThread(Person person){ 7 | this.person = person; 8 | } 9 | 10 | @Override 11 | public void run() { 12 | while (true){ 13 | System.out.println("The thread " + Thread.currentThread().getName() + " " + person.getName() + " " + person.getAddress()); 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/com/chao/concurrency_basic/chapter10_CUSTOM_LOCK/Lock.java: -------------------------------------------------------------------------------- 1 | package com.chao.concurrency_basic.chapter10_CUSTOM_LOCK; 2 | 3 | import java.util.Collection; 4 | 5 | public interface Lock { 6 | 7 | class TimeoutException extends Exception{ 8 | TimeoutException(String msg){ 9 | super(msg); 10 | } 11 | } 12 | 13 | void lock(); 14 | 15 | void lock(long mills) throws TimeoutException; 16 | 17 | void unlock(); 18 | 19 | Collection getBlockedCollection(); 20 | 21 | int getCollectionOfBlockedThreadSize(); 22 | 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/com/chao/concurrency_basic/chapter2/bank2/TicketWindowRunnable.java: -------------------------------------------------------------------------------- 1 | package com.chao.concurrency_basic.chapter2.bank2; 2 | 3 | public class TicketWindowRunnable implements Runnable { 4 | 5 | private int index = 1; 6 | 7 | private final static int MAX = 1000; 8 | 9 | public void run() { 10 | while (index <= MAX){ 11 | System.out.println(Thread.currentThread() + "的号码是" + (index++)); 12 | try { 13 | Thread.sleep(1000); 14 | } catch (InterruptedException e) { 15 | e.printStackTrace(); 16 | } 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/com/chao/design_pattern/chapter1/SingletonObject3.java: -------------------------------------------------------------------------------- 1 | package com.chao.design_pattern.chapter1; 2 | 3 | /** 4 | * 解决了懒加载、多实例的问题 5 | * 但是除了第一个线程外是创建实例,其他线程都是读的操作, 6 | * 都需要等待前一个线程完成读操作,影响性能 7 | */ 8 | 9 | public class SingletonObject3 { 10 | 11 | private static SingletonObject3 instance; 12 | 13 | private SingletonObject3(){} 14 | 15 | public synchronized static SingletonObject3 getInstance(){ 16 | if(null == instance){ 17 | instance = new SingletonObject3(); 18 | } 19 | return SingletonObject3.instance; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/com/chao/design_pattern/chapter1/SingletonObject7.java: -------------------------------------------------------------------------------- 1 | package com.chao.design_pattern.chapter1; 2 | 3 | public class SingletonObject7 { 4 | private SingletonObject7(){} 5 | 6 | private enum Singleton{ 7 | INSTANCE; 8 | private final SingletonObject7 instance; 9 | Singleton(){ 10 | instance = new SingletonObject7(); 11 | } 12 | 13 | public SingletonObject7 getInstance(){ 14 | return instance; 15 | } 16 | } 17 | public static SingletonObject7 getInstance(){ 18 | return Singleton.INSTANCE.getInstance(); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/com/chao/design_pattern/chapter18_ACTIVE_OBJECT_important/Client.java: -------------------------------------------------------------------------------- 1 | package com.chao.design_pattern.chapter18_ACTIVE_OBJECT_important; 2 | 3 | public class Client { 4 | public static void main(String[] args) { 5 | ActiveObject activeObject = ActiveObjectFactory.createActiveObject(); 6 | // 两个MakeString的方法调用者 7 | new MakerClientThread("Alice", activeObject).start(); 8 | new MakerClientThread("Bobby", activeObject).start(); 9 | 10 | // DisplayString的方法调用者 11 | new DisplayClientThread("Chris", activeObject).start(); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/main/java/com/chao/design_pattern/chapter6_READ_WRITE_LOCK/note.txt: -------------------------------------------------------------------------------- 1 | 2 | 1. reading, other thread will enter to the wait set 3 | 2. read write 锁分离 4 | 5 | 6 | 规则: 7 | 1. read read 并行化 8 | 2. read write 不允许 9 | 3. write write 不允许 10 | 11 | 是否进行串行化(加锁)处理[y/n?] 12 | +-------------------------+ 13 | + |READ | WRITE + 14 | +-------------------------+ 15 | + READ | N | Y + 16 | +-------------------------+ 17 | +WRITE | Y | Y + 18 | +-------------------------+ 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /src/main/java/com/chao/design_pattern/chapter15_THREAD_PER_MESSAGE/MessageRequestClient.java: -------------------------------------------------------------------------------- 1 | package com.chao.design_pattern.chapter15_THREAD_PER_MESSAGE; 2 | 3 | import java.util.stream.IntStream; 4 | 5 | public class MessageRequestClient { 6 | 7 | public static void main(String[] args) { 8 | MessageHandle handle = new MessageHandle(); 9 | IntStream.rangeClosed(1, 10).forEach(i -> new Thread(() -> { 10 | Message message = new Message(String.valueOf(i)); 11 | handle.request(message); 12 | }).start()); 13 | 14 | handle.shutdown(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /src/main/java/com/chao/design_pattern/chapter1/SingletonObject5.java: -------------------------------------------------------------------------------- 1 | package com.chao.design_pattern.chapter1; 2 | 3 | public class SingletonObject5 { 4 | 5 | private static volatile SingletonObject5 instance; 6 | 7 | private SingletonObject5(){} 8 | 9 | // double check and volatile 10 | public static SingletonObject5 getInstance(){ 11 | if(null == instance){ 12 | synchronized (SingletonObject5.class){ 13 | if(null == instance){ 14 | instance = new SingletonObject5(); 15 | } 16 | } 17 | } 18 | return SingletonObject5.instance; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/com/chao/design_pattern/chapter5_SINGLE_THREADED_EXECUTION/User.java: -------------------------------------------------------------------------------- 1 | package com.chao.design_pattern.chapter5_SINGLE_THREADED_EXECUTION; 2 | 3 | public class User extends Thread { 4 | private Gate gate; 5 | private String name; 6 | private String address; 7 | 8 | public User(Gate gate, String name, String address) { 9 | this.gate = gate; 10 | this.name = name; 11 | this.address = address; 12 | } 13 | 14 | @Override 15 | public void run() { 16 | int i = 0; 17 | while (true) { 18 | gate.pass(name, address); 19 | ++i; 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/com/chao/design_pattern/chapter11/ContextClient.java: -------------------------------------------------------------------------------- 1 | package com.chao.design_pattern.chapter11; 2 | 3 | import java.util.stream.IntStream; 4 | 5 | public class ContextClient { 6 | 7 | public static void main(String[] args) { 8 | IntStream.range(1,5).forEach(i->{ 9 | Context context = new Context(); 10 | ExecutionTask executionTask = new ExecutionTask(context); 11 | new Thread(()->{ 12 | executionTask.run(); 13 | System.out.println(context.getName()); 14 | System.out.println(context.getCardId()); 15 | }).start(); 16 | }); 17 | 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /.idea/compiler.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /src/main/java/com/chao/design_pattern/chapter16_TWO_PHASE_TERMINATE/custom_test/TerminationRequester.java: -------------------------------------------------------------------------------- 1 | package com.chao.design_pattern.chapter16_TWO_PHASE_TERMINATE.custom_test; 2 | 3 | public class TerminationRequester { 4 | public static void main(String[] args) throws InterruptedException { 5 | Terminator terminator = new Terminator(); 6 | terminator.start(); 7 | // 表示主线程做自己的工作 8 | Thread.sleep(5_000); 9 | // 发出指令终止线程 10 | terminator.terminate(); 11 | // 主线程等待线程的终止 12 | terminator.join(); 13 | 14 | System.out.println("Termination request is successful"); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/com/chao/design_pattern/chapter18_ACTIVE_OBJECT_important/DisplayStringRequest.java: -------------------------------------------------------------------------------- 1 | package com.chao.design_pattern.chapter18_ACTIVE_OBJECT_important; 2 | 3 | /** 4 | * {@link ActiveObject#displayString(String)} 5 | * displayString()的方法请求对象 6 | */ 7 | public class DisplayStringRequest extends MethodRequest { 8 | private final String text; 9 | 10 | protected DisplayStringRequest(Servant servant, String text) { 11 | super(servant, null); 12 | this.text = text; 13 | } 14 | 15 | @Override 16 | public void execute() { 17 | this.servant.displayString(text); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/com/chao/concurrency_basic/chapter4/DaemonThread.java: -------------------------------------------------------------------------------- 1 | package com.chao.concurrency_basic.chapter4; 2 | 3 | public class DaemonThread { 4 | public static void main(String[] args) { 5 | Thread t = new Thread(){ 6 | @Override 7 | public void run() { 8 | System.out.println(Thread.currentThread().getName()); 9 | try { 10 | Thread.sleep(1000); 11 | } catch (InterruptedException e) { 12 | e.printStackTrace(); 13 | } 14 | System.out.println("done."); 15 | } 16 | }; 17 | 18 | // 设置为守护线程 19 | t.setDaemon(true); 20 | 21 | t.start(); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/com/chao/concurrency_basic/chapter8/OtherService.java: -------------------------------------------------------------------------------- 1 | package com.chao.concurrency_basic.chapter8; 2 | 3 | public class OtherService { 4 | private DeadLock deadLock; 5 | 6 | private static final Object LOCK = new Object(); 7 | 8 | public void o1() { 9 | synchronized (LOCK){ 10 | System.out.println("o1==========="); 11 | deadLock.d2(); 12 | } 13 | } 14 | 15 | public void o2() { 16 | synchronized (LOCK){ 17 | System.out.println("o1==========="); 18 | } 19 | } 20 | 21 | public void setDeadLock(DeadLock deadLock) { 22 | this.deadLock = deadLock; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/com/chao/design_pattern/chapter11/QueryFromDBAction.java: -------------------------------------------------------------------------------- 1 | package com.chao.design_pattern.chapter11; 2 | 3 | import java.util.Random; 4 | 5 | public class QueryFromDBAction { 6 | private static Random random = new Random(System.currentTimeMillis()); 7 | public void execute(){ 8 | try { 9 | Thread.sleep(random.nextInt(1000)); 10 | String name = "leo " + Thread.currentThread().getName(); 11 | Context context = ActionContext.getActionContext().getContext(); 12 | context.setName(name); 13 | } catch (InterruptedException e) { 14 | e.printStackTrace(); 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/com/chao/concurrency_basic/chapter8/DeadLock.java: -------------------------------------------------------------------------------- 1 | package com.chao.concurrency_basic.chapter8; 2 | 3 | public class DeadLock { 4 | private OtherService otherService; 5 | 6 | private static final Object LOCK = new Object(); 7 | 8 | public DeadLock(OtherService otherService){ 9 | this.otherService = otherService; 10 | } 11 | 12 | public void d1(){ 13 | synchronized (LOCK){ 14 | System.out.println("d1==========="); 15 | otherService.o2(); 16 | } 17 | } 18 | 19 | public void d2(){ 20 | synchronized (LOCK){ 21 | System.out.println("d1==========="); 22 | } 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/com/chao/design_pattern/chapter6_READ_WRITE_LOCK/ReadWriteLockTest.java: -------------------------------------------------------------------------------- 1 | package com.chao.design_pattern.chapter6_READ_WRITE_LOCK; 2 | 3 | public class ReadWriteLockTest { 4 | public static void main(String[] args) { 5 | SharedData data = new SharedData(10); 6 | new ReadWorker(data, "1").start(); 7 | new ReadWorker(data, "2").start(); 8 | new ReadWorker(data, "3").start(); 9 | new ReadWorker(data, "4").start(); 10 | new ReadWorker(data, "5").start(); 11 | 12 | new WriteWorker(data, "1", "qwertyuiop").start(); 13 | new WriteWorker(data, "2", "QWERTYUIOP").start(); 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/com/chao/design_pattern/chapter14_CUSTOM_COUNT_DOWN_LATCH/CountDown.java: -------------------------------------------------------------------------------- 1 | package com.chao.design_pattern.chapter14_CUSTOM_COUNT_DOWN_LATCH; 2 | 3 | public class CountDown { 4 | private int total; 5 | private int count; 6 | 7 | public CountDown(int total) { 8 | this.total = total; 9 | this.count = 0; 10 | } 11 | 12 | public void cut(){ 13 | synchronized (this){ 14 | total--; 15 | this.notifyAll(); 16 | } 17 | } 18 | 19 | public void await() throws InterruptedException { 20 | synchronized (this){ 21 | while (count != total){ 22 | this.wait(); 23 | } 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/com/chao/design_pattern/chapter8_FUTURE/AsynFuture.java: -------------------------------------------------------------------------------- 1 | package com.chao.design_pattern.chapter8_FUTURE; 2 | 3 | public class AsynFuture implements Future { 4 | private volatile boolean done = false; 5 | private T result; 6 | 7 | public void done(T result){ 8 | synchronized (this){ 9 | this.result = result; 10 | // 通知等待取结果的线程可以取走结果 11 | this.done = true; 12 | this.notifyAll(); 13 | } 14 | } 15 | 16 | @Override 17 | public T get() throws InterruptedException { 18 | synchronized (this){ 19 | while (!done){ 20 | this.wait(); 21 | } 22 | } 23 | return result; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/com/chao/design_pattern/chapter4_OBSERVER/normal_observer_pattern/ObserverClient.java: -------------------------------------------------------------------------------- 1 | package com.chao.design_pattern.chapter4_OBSERVER.normal_observer_pattern; 2 | 3 | public class ObserverClient { 4 | public static void main(String[] args) { 5 | Subject subject = new Subject(); 6 | new BinaryObserver(subject); 7 | new OctalObserver(subject); 8 | System.out.println("=============="); 9 | subject.setStatus(10); 10 | System.out.println("=============="); 11 | subject.setStatus(10); 12 | System.out.println("=============="); 13 | subject.setStatus(15); 14 | System.out.println("=============="); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/com/chao/concurrency_basic/chapter12/note.txt: -------------------------------------------------------------------------------- 1 | 1.main线程属于线程组main 2 | 3 | 2.一个线程创建的时候,如果没有指定ThreadGroup,则将该线程加入创建该线程的线程(父线程)所属的线程组 4 | 5 | 3.一个ThreadGroup可以拥有多个线程,也可以拥有多个线程组 6 | 7 | 4.在其他的线程组中(两个线程组不相关),其中一个线程组可以访问另一个线程组的相关信息 8 | 9 | 5.activeGroupCount()可以检测当前线程组下有多少个活动的线程组 10 | checkAccess()可以评估当前线程是否可以修改某个线程组 destroy()可以销毁某个线程组及其子线程和子线程组,但要保证被销毁的线程组内没有活动线程或线程组,否则抛出异常 11 | enumerate(Thread[] list, boolean recurse)可以复制线程组中的线程到list中,当recurse为true时,将线程组中的子线程组中的线程也一并复制 12 | 13 | 6.interrupt()会中断线程组内所有线程,包括子线程组中的所有线程 14 | 15 | 7.setDaemon()将线程组设置为守护线程组,当父线程组消亡时,它也会消亡,而守护线程组要等待线程组中最后一个线程死亡才会死亡,这时若要强制守护线程组死亡,需要显示调用destroy() 16 | 17 | 18 | -------------------------------------------------------------------------------- /src/main/java/com/chao/concurrency_basic/chapter7/TicketWindowRunnable.java: -------------------------------------------------------------------------------- 1 | package com.chao.concurrency_basic.chapter7; 2 | 3 | public class TicketWindowRunnable implements Runnable { 4 | private int index = 1; 5 | private final static int MAX = 500; 6 | 7 | private final Object MONITOR = new Object(); 8 | 9 | public void run() { 10 | while (true){ 11 | synchronized (MONITOR){ 12 | if(index > MAX) 13 | break; 14 | try { 15 | Thread.sleep(5); 16 | } catch (InterruptedException e) { 17 | e.printStackTrace(); 18 | } 19 | 20 | System.out.println(Thread.currentThread() + "的号码是" + (index++)); 21 | } 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/com/chao/concurrency_basic/chapter1/TemplateMethod.java: -------------------------------------------------------------------------------- 1 | package com.chao.concurrency_basic.chapter1; 2 | 3 | public class TemplateMethod { 4 | 5 | public final void templateMethod(){ 6 | System.out.println("******************************"); 7 | print(); 8 | System.out.println("******************************"); 9 | } 10 | 11 | protected void print(){ 12 | // override this method 13 | } 14 | 15 | public static void main(String[] args) { 16 | TemplateMethod t = new TemplateMethod(){ 17 | @Override 18 | protected void print() { 19 | System.out.println("** template method **"); 20 | } 21 | }; 22 | t.templateMethod(); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/com/chao/concurrency_basic/chapter6/ThreadCloseGraceful2.java: -------------------------------------------------------------------------------- 1 | package com.chao.concurrency_basic.chapter6; 2 | 3 | public class ThreadCloseGraceful2 { 4 | 5 | public static void main(String[] args) { 6 | Worker w = new Worker(); 7 | w.start(); 8 | try { 9 | Thread.sleep(100); 10 | } catch (InterruptedException e) { 11 | e.printStackTrace(); 12 | } 13 | 14 | w.interrupt(); 15 | } 16 | 17 | private static class Worker extends Thread{ 18 | 19 | @Override 20 | public void run() { 21 | while (true){ 22 | if(Thread.interrupted()){ 23 | break; 24 | } 25 | } 26 | 27 | // do other thing... 28 | } 29 | 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/com/chao/design_pattern/chapter7_IMMUTABLE_DESIGN_PATTERN/Person.java: -------------------------------------------------------------------------------- 1 | package com.chao.design_pattern.chapter7_IMMUTABLE_DESIGN_PATTERN; 2 | 3 | public final class Person { 4 | private final String name; 5 | private final String address; 6 | 7 | public Person(String name, String address) { 8 | this.name = name; 9 | this.address = address; 10 | } 11 | 12 | public String getName() { 13 | return name; 14 | } 15 | 16 | public String getAddress() { 17 | return address; 18 | } 19 | 20 | @Override 21 | public String toString() { 22 | return "Person{" + 23 | "name='" + name + '\'' + 24 | ", address='" + address + '\'' + 25 | '}'; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/com/chao/concurrency_basic/chapter8/DeadLockTest.java: -------------------------------------------------------------------------------- 1 | package com.chao.concurrency_basic.chapter8; 2 | 3 | public class DeadLockTest { 4 | public static void main(String[] args) { 5 | OtherService otherService = new OtherService(); 6 | DeadLock deadLock = new DeadLock(otherService); 7 | otherService.setDeadLock(deadLock); 8 | 9 | /** 10 | * cmd通过jps命令查看该main线程的端口号 11 | * 再通过jstack + 上面查到的端口号的命令查看栈情况 12 | * 可以分析出来死锁情况:是否存在死锁 13 | */ 14 | new Thread(()->{ 15 | while (true){ 16 | deadLock.d1(); 17 | } 18 | }).start(); 19 | new Thread(()->{ 20 | while (true){ 21 | otherService.o1(); 22 | } 23 | }).start(); 24 | 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/com/chao/design_pattern/chapter11/ExecutionTask.java: -------------------------------------------------------------------------------- 1 | package com.chao.design_pattern.chapter11; 2 | 3 | public class ExecutionTask implements Runnable{ 4 | private Context context; 5 | 6 | public ExecutionTask(Context context) { 7 | this.context = context; 8 | } 9 | 10 | @Override 11 | public void run() { 12 | ActionContext.threadLocal.set(context); 13 | QueryFromDBAction queryFromDBAction = new QueryFromDBAction(); 14 | queryFromDBAction.execute(); 15 | try { 16 | Thread.sleep(500); 17 | } catch (InterruptedException e) { 18 | e.printStackTrace(); 19 | } 20 | QueryFromHttp queryFromHttp = new QueryFromHttp(); 21 | queryFromHttp.execute(); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/com/chao/concurrency_basic/chapter4/DaemonThread2.java: -------------------------------------------------------------------------------- 1 | package com.chao.concurrency_basic.chapter4; 2 | 3 | public class DaemonThread2 { 4 | 5 | public static void main(String[] args) { 6 | Thread t = new Thread(()->{ 7 | Thread innerThread = new Thread(()->{ 8 | while (true){ 9 | // only run a once 10 | System.out.println("Do something..."); 11 | } 12 | }); 13 | 14 | innerThread.setDaemon(true); 15 | innerThread.start(); 16 | }); 17 | 18 | try { 19 | Thread.sleep(1_000); 20 | System.out.println("T thread finish done."); 21 | } catch (InterruptedException e) { 22 | e.printStackTrace(); 23 | } 24 | t.start(); 25 | 26 | 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/com/chao/concurrency_basic/chapter12/ThreadGroupAPI.java: -------------------------------------------------------------------------------- 1 | package com.chao.concurrency_basic.chapter12; 2 | 3 | public class ThreadGroupAPI { 4 | public static void main(String[] args) throws InterruptedException { 5 | ThreadGroup tg1 = new ThreadGroup("TG1"); 6 | 7 | Thread t = new Thread(tg1,"t1"){ 8 | @Override 9 | public void run() { 10 | try { 11 | Thread.sleep(5_000); 12 | } catch (InterruptedException e) { 13 | e.printStackTrace(); 14 | } 15 | } 16 | }; 17 | 18 | // tg1.setDaemon(true); 19 | Thread.sleep(2_000); 20 | System.out.println(tg1.isDestroyed()); 21 | tg1.destroy(); 22 | System.out.println(tg1.isDestroyed()); 23 | } 24 | 25 | 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/com/chao/design_pattern/chapter6_READ_WRITE_LOCK/ReadWorker.java: -------------------------------------------------------------------------------- 1 | package com.chao.design_pattern.chapter6_READ_WRITE_LOCK; 2 | 3 | public class ReadWorker extends Thread { 4 | private SharedData sharedData; 5 | 6 | public ReadWorker(SharedData sharedData, String name) { 7 | super(name); 8 | this.sharedData = sharedData; 9 | } 10 | 11 | @Override 12 | public void run() { 13 | try { 14 | while (true) { 15 | String data = sharedData.read(); 16 | System.out.println("The read thread [" + Thread.currentThread().getName() + "] print data : " + data); 17 | Thread.sleep(100); 18 | } 19 | } catch (InterruptedException e) { 20 | e.printStackTrace(); 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/com/chao/design_pattern/chapter13_PRODUCER_CONSUMER/ProducerAndConsumerClient.java: -------------------------------------------------------------------------------- 1 | package com.chao.design_pattern.chapter13_PRODUCER_CONSUMER; 2 | 3 | import java.util.concurrent.atomic.AtomicInteger; 4 | import java.util.stream.IntStream; 5 | 6 | public class ProducerAndConsumerClient { 7 | public static void main(String[] args) { 8 | MessageQueue queue = new MessageQueue(); 9 | AtomicInteger goods = new AtomicInteger(); 10 | 11 | IntStream.range(1,3) 12 | .forEach(i-> new ProducerThread(queue, String.valueOf(i), String.valueOf(goods.getAndIncrement())).start()); 13 | 14 | IntStream.range(1,10) 15 | .forEach(i-> new ConsumerThread(queue, String.valueOf(i)).start()); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/com/chao/concurrency_basic/chapter6/ThreadCloseGraceful.java: -------------------------------------------------------------------------------- 1 | package com.chao.concurrency_basic.chapter6; 2 | 3 | public class ThreadCloseGraceful { 4 | 5 | public static void main(String[] args) { 6 | Worker w = new Worker(); 7 | w.start(); 8 | 9 | try { 10 | Thread.sleep(1000); 11 | } catch (InterruptedException e) { 12 | e.printStackTrace(); 13 | } 14 | 15 | w.shutdown(); 16 | } 17 | 18 | 19 | private static class Worker extends Thread{ 20 | private volatile boolean start = true; 21 | 22 | @Override 23 | public void run() { 24 | while (start){ 25 | // do something 26 | } 27 | } 28 | 29 | public void shutdown(){ 30 | this.start = false; 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/com/chao/concurrency_basic/chapter4/ThreadSimpleAPI.java: -------------------------------------------------------------------------------- 1 | package com.chao.concurrency_basic.chapter4; 2 | 3 | import java.util.Optional; 4 | 5 | public class ThreadSimpleAPI { 6 | 7 | public static void main(String[] args) { 8 | Thread t = new Thread(()->{ 9 | Optional.of("Hello").ifPresent(System.out::println); 10 | try { 11 | Thread.sleep(10_000); 12 | } catch (InterruptedException e) { 13 | e.printStackTrace(); 14 | } 15 | },"t1"); 16 | 17 | t.start(); 18 | 19 | Optional.of(t.getName()).ifPresent(System.out::println); 20 | // id表示该线程第n个被创建时的数字 21 | Optional.of(t.getId()).ifPresent(System.out::println); 22 | Optional.of(t.getPriority()).ifPresent(System.out::println); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/com/chao/design_pattern/chapter1/SingletonObject4.java: -------------------------------------------------------------------------------- 1 | package com.chao.design_pattern.chapter1; 2 | 3 | /** 4 | * 解决了性能问题 5 | * 6 | * 可能会出现NullPointException 7 | */ 8 | 9 | public class SingletonObject4 { 10 | 11 | private static SingletonObject4 instance; 12 | // private Object obj; 13 | 14 | private SingletonObject4(){ 15 | // do some heavy things 16 | // int i=0, j=10; 17 | // obj = new Object(); 18 | // ... 19 | } 20 | 21 | public static SingletonObject4 getInstance(){ 22 | if(null == instance){ 23 | synchronized (SingletonObject4.class){ 24 | if(null == instance){ 25 | instance = new SingletonObject4(); 26 | } 27 | } 28 | } 29 | return SingletonObject4.instance; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/com/chao/design_pattern/chapter18_ACTIVE_OBJECT_important/ActiveObjectFactory.java: -------------------------------------------------------------------------------- 1 | package com.chao.design_pattern.chapter18_ACTIVE_OBJECT_important; 2 | 3 | public class ActiveObjectFactory { 4 | private ActiveObjectFactory() { 5 | } 6 | 7 | /** 8 | * 创建上下文信息 9 | * @return 返回proxy对象 10 | */ 11 | public static ActiveObject createActiveObject() { 12 | Servant servant = new Servant(); 13 | ActivationQueue activationQueue = new ActivationQueue(); 14 | SchedulerThread schedulerThread = new SchedulerThread(activationQueue); 15 | ActiveObjectProxy activeObjectProxy = new ActiveObjectProxy(schedulerThread, servant); 16 | // 工作者线程开启 17 | schedulerThread.start(); 18 | return activeObjectProxy; 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/com/chao/concurrency_basic/chapter7/SynchronizedTest.java: -------------------------------------------------------------------------------- 1 | package com.chao.concurrency_basic.chapter7; 2 | 3 | public class SynchronizedTest { 4 | private static final Object LOCK = new Object(); 5 | 6 | public static void main(String[] args) { 7 | Runnable runnable = new Runnable() { 8 | @Override 9 | public void run() { 10 | synchronized (LOCK){ 11 | try { 12 | Thread.sleep(200_000); 13 | } catch (InterruptedException e) { 14 | e.printStackTrace(); 15 | } 16 | } 17 | } 18 | }; 19 | 20 | Thread t1 = new Thread(runnable); 21 | Thread t2 = new Thread(runnable); 22 | Thread t3 = new Thread(runnable); 23 | 24 | t1.start(); 25 | t2.start(); 26 | t3.start(); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/com/chao/design_pattern/chapter8_FUTURE/note.txt: -------------------------------------------------------------------------------- 1 | 2 | 大概结构 3 | 4 | [(I)Future{get();}] <---impl---- [(C)AsynFuture{done(); get();}] 5 | | 6 | | 7 | (combination) 8 | | 9 | | 10 | [(C)FutureService{ Future submit(FutureTask);}] 11 | | 12 | | 13 | (combination) 14 | | 15 | | 16 | [(I)FutureTask{call();}] 17 | 18 | 19 | 20 | 总体思路: 21 | 22 | 1.Future提供获取结果的接口get();FutureTask提供放置任务的接口call() 23 | 2.FutureService对外提供提交任务的Future submit(FutureTask)方法,该方法将上述两个接口桥接起来,调用该方法时使用一个线程t去完成任务,而立即返回结果对象task; 24 | 3.线程t完成任务后,将对象task的结果设置为计算结果 25 | 3.1 在线程t完成任务之前,所有获取结果(调用get())的线程将被阻塞,直到完成后将其唤醒获取结果; 26 | 3.2 若调用get()之前线程t已经完成任务,那么可以直接获取结果 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /src/main/java/com/chao/design_pattern/chapter4_OBSERVER/normal_observer_pattern/Subject.java: -------------------------------------------------------------------------------- 1 | package com.chao.design_pattern.chapter4_OBSERVER.normal_observer_pattern; 2 | 3 | import java.util.ArrayList; 4 | 5 | public class Subject { 6 | private int status; 7 | 8 | private ArrayList observers = new ArrayList<>(); 9 | 10 | public int getStatus() { 11 | return status; 12 | } 13 | 14 | public void attach(Observer observer){ 15 | observers.add(observer); 16 | } 17 | 18 | public void setStatus(int status) { 19 | if(this.status == status){ 20 | return; 21 | } 22 | this.status = status; 23 | notifyAllObservers(); 24 | } 25 | private void notifyAllObservers() { 26 | observers.forEach(Observer::update); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/com/chao/concurrency_basic/chapter11/ThreadException.java: -------------------------------------------------------------------------------- 1 | package com.chao.concurrency_basic.chapter11; 2 | 3 | public class ThreadException { 4 | public static final int A = 10; 5 | public static final int B = 0; 6 | 7 | public static void main(String[] args) { 8 | Thread t = new Thread(()->{ 9 | try { 10 | Thread.sleep(5_000); 11 | int result = A / B; 12 | System.out.println(result); 13 | } catch (InterruptedException e) { 14 | e.printStackTrace(); 15 | } 16 | }); 17 | 18 | /** 19 | * 可以通过接口方法,捕获到异常之后, 20 | * 对异常和发生异常的线程做一些事情 21 | */ 22 | t.setUncaughtExceptionHandler((thread,e)->{ 23 | System.out.println(e); 24 | System.out.println(thread); 25 | }); 26 | 27 | t.start(); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/com/chao/design_pattern/chapter11/QueryFromHttp.java: -------------------------------------------------------------------------------- 1 | package com.chao.design_pattern.chapter11; 2 | 3 | import java.util.Random; 4 | 5 | public class QueryFromHttp { 6 | private static Random random = new Random(System.currentTimeMillis()); 7 | public void execute(){ 8 | try { 9 | Thread.sleep(random.nextInt(1000)); 10 | Context context = ActionContext.getActionContext().getContext(); 11 | String name = context.getName(); 12 | String cardId = initValue(name); 13 | context.setCardId(cardId); 14 | context.setName(name); 15 | } catch (InterruptedException e) { 16 | e.printStackTrace(); 17 | } 18 | } 19 | 20 | private String initValue(String name) { 21 | return "2342345345 " + Thread.currentThread().getName(); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/com/chao/design_pattern/chapter18_ACTIVE_OBJECT_important/MakeStringRequest.java: -------------------------------------------------------------------------------- 1 | package com.chao.design_pattern.chapter18_ACTIVE_OBJECT_important; 2 | 3 | 4 | /** 5 | * {@link ActiveObject#makeString(int, char)} 6 | * makeString()的方法请求对象 7 | */ 8 | public class MakeStringRequest extends MethodRequest { 9 | private final int count; 10 | private final char fillChar; 11 | 12 | protected MakeStringRequest(Servant servant, FutureResult futureResult, int count, char fillChar) { 13 | super(servant, futureResult); 14 | this.count = count; 15 | this.fillChar = fillChar; 16 | } 17 | 18 | @Override 19 | public void execute() { 20 | Result result = this.servant.makeString(count,fillChar ); 21 | this.futureResult.setResult(result); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/com/chao/concurrency_basic/chapter2/tax/TaxCalculatorMain.java: -------------------------------------------------------------------------------- 1 | package com.chao.concurrency_basic.chapter2.tax; 2 | 3 | public class TaxCalculatorMain { 4 | public static void main(String[] args) { 5 | /* TaxCalculator taxCalculator = new TaxCalculator(10000d,2000d){ 6 | @Override 7 | protected double calcTax() { 8 | return getSalary()*0.1 + getBonus()*0.15; 9 | } 10 | }; 11 | 12 | System.out.println(taxCalculator.calculate());*/ 13 | 14 | 15 | TaxCalculator taxCalculator = new TaxCalculator(10000d,2000d); 16 | CalculatorStrategy calculatorStrategy = new SimpleCalculatorStrategy(); 17 | taxCalculator.setCalculatorStrategy(calculatorStrategy); 18 | double tax = taxCalculator.calculate(); 19 | System.out.println(tax); 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/com/chao/design_pattern/chapter18_ACTIVE_OBJECT_important/FutureResult.java: -------------------------------------------------------------------------------- 1 | package com.chao.design_pattern.chapter18_ACTIVE_OBJECT_important; 2 | 3 | public class FutureResult implements Result { 4 | 5 | private Result result; 6 | private boolean ready = false; 7 | 8 | public synchronized void setResult(Result result){ 9 | this.ready = true; 10 | this.result = result; 11 | this.notifyAll(); 12 | } 13 | 14 | /** 15 | * 当其他线程需要获取结果时, 16 | * 如若结果未准备好,需要等待, 17 | * 并等待其他线程的唤醒 18 | */ 19 | @Override 20 | public synchronized Object getResultValue() { 21 | while (!ready){ 22 | try { 23 | this.wait(); 24 | } catch (InterruptedException e) { 25 | e.printStackTrace(); 26 | } 27 | } 28 | return this.result.getResultValue(); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/com/chao/concurrency_basic/chapter3/note.txt: -------------------------------------------------------------------------------- 1 | 1. 创建线程对象Thread,默认有一个线程名,以Thread-开头,从0开始计数,而这个数字是线程安全的 2 | private volatile int threadStatus = 0; 3 | private static synchronized long nextThreadID() { 4 | return ++threadSeqNumber; 5 | } 6 | 如果是构造时命名就不会调用nextThreadID() 7 | 构造函数Thread() 8 | 例如:Thread-0 9 | Thread-1 10 | Thread-2 11 | 12 | 2.如果在构造Thread的时候没有传递Runnable或者没有覆写Thread的run()方法,该Thread将不会调用任何东西(因为传入的值为null),如果传递了Runnable接口的实例,或者覆写了Thread的run()方法,则会执行该方法的逻辑单元(逻辑代码) 13 | 14 | 3.如果构造线程对象未传入ThreadGroup,Thread会默认获取父线程的ThreadGroup作为该线程的ThreadGroup,此时子线程和父线程会在同一个ThreadGroup中 15 | 16 | 4.构造Thread的时候传入stackSize代表着该线程占用的stack大小,如果没有指定stackSize的大小,默认为0(0代表该参数会被忽略),该参数会被JNI函数去使用,需要注意的是,该参数高度依赖平台,在一些平台可能会无效。一般来说,stackSize越大,可创建的线程就会越少 17 | 18 | 19 | -------------------------------------------------------------------------------- /src/main/java/com/chao/design_pattern/chapter9/RequestClient.java: -------------------------------------------------------------------------------- 1 | package com.chao.design_pattern.chapter9; 2 | 3 | import java.util.Random; 4 | 5 | public class RequestClient extends Thread{ 6 | private final RequestQueue queue; 7 | private final String value; 8 | private final Random random; 9 | 10 | public RequestClient(RequestQueue queue, String value) { 11 | this.queue = queue; 12 | this.value = value; 13 | this.random = new Random(); 14 | } 15 | 16 | @Override 17 | public void run() { 18 | int i=0; 19 | while (i<100){ 20 | System.out.println("ClientAndService -> " + value); 21 | queue.pushRequest(new Request(value)); 22 | try { 23 | Thread.sleep(random.nextInt(1000)); 24 | } catch (InterruptedException e) { 25 | e.printStackTrace(); 26 | } 27 | i++; 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/com/chao/design_pattern/chapter9/RequestQueue.java: -------------------------------------------------------------------------------- 1 | package com.chao.design_pattern.chapter9; 2 | 3 | import java.util.LinkedList; 4 | 5 | public class RequestQueue { 6 | private static final LinkedList requestLinkedList = new LinkedList<>(); 7 | 8 | public Request popRequest(){ 9 | synchronized (requestLinkedList){ 10 | if(requestLinkedList.size() <= 0){ 11 | try { 12 | requestLinkedList.wait(); 13 | } catch (InterruptedException e) { 14 | // 线程被中断则直接返回null,代表没有取到请求 15 | return null; 16 | } 17 | } 18 | return requestLinkedList.removeFirst(); 19 | } 20 | } 21 | 22 | public void pushRequest(Request request){ 23 | synchronized (requestLinkedList){ 24 | requestLinkedList.addLast(request); 25 | requestLinkedList.notifyAll(); 26 | } 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/com/chao/design_pattern/chapter13_PRODUCER_CONSUMER/ConsumerThread.java: -------------------------------------------------------------------------------- 1 | package com.chao.design_pattern.chapter13_PRODUCER_CONSUMER; 2 | 3 | import java.util.Random; 4 | 5 | public class ConsumerThread extends Thread{ 6 | private MessageQueue queue; 7 | 8 | private static final Random random = new Random(); 9 | 10 | public ConsumerThread(MessageQueue queue, String name) { 11 | super(name); 12 | this.queue = queue; 13 | } 14 | 15 | @Override 16 | public void run() { 17 | while (true){ 18 | Message message = queue.take(); 19 | System.out.println("ConsumerThread-" + Thread.currentThread().getName() + " take a message is " + message.getMsg()); 20 | try { 21 | Thread.sleep(random.nextInt(1000)); 22 | } catch (InterruptedException e) { 23 | e.printStackTrace(); 24 | } 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/com/chao/design_pattern/chapter17_WORKER_THREAD/WorkerTread.java: -------------------------------------------------------------------------------- 1 | package com.chao.design_pattern.chapter17_WORKER_THREAD; 2 | 3 | import java.util.Random; 4 | 5 | public class WorkerTread extends Thread { 6 | private String name; 7 | private final Channel channel; 8 | 9 | private static final Random random = new Random(System.currentTimeMillis()); 10 | 11 | public WorkerTread(String name, Channel channel) { 12 | super(name); 13 | this.channel = channel; 14 | } 15 | 16 | @Override 17 | public void run() { 18 | while (true) { 19 | Request request = channel.take(); 20 | System.out.println(getName() + " take the msg -> " + request.getMsg()); 21 | try { 22 | Thread.sleep(random.nextInt(1_000)); 23 | } catch (InterruptedException e) { 24 | e.printStackTrace(); 25 | } 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/com/chao/design_pattern/chapter18_ACTIVE_OBJECT_important/DisplayClientThread.java: -------------------------------------------------------------------------------- 1 | package com.chao.design_pattern.chapter18_ACTIVE_OBJECT_important; 2 | 3 | public class DisplayClientThread extends Thread { 4 | 5 | private final ActiveObject activeObject; 6 | 7 | public DisplayClientThread(String name, ActiveObject activeObject) { 8 | super(name); 9 | this.activeObject = activeObject; 10 | } 11 | 12 | @Override 13 | public void run() { 14 | try { 15 | for (int i = 0; true; i++) { 16 | /** 17 | * 通过proxy进行方法调用 18 | * 返回的result是FutureResult对象 19 | */ 20 | String text = Thread.currentThread().getName() + "->" + i; 21 | activeObject.displayString(text); 22 | Thread.sleep(200); 23 | } 24 | } catch (InterruptedException e) { 25 | e.printStackTrace(); 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/com/chao/design_pattern/chapter18_ACTIVE_OBJECT_important/SchedulerThread.java: -------------------------------------------------------------------------------- 1 | package com.chao.design_pattern.chapter18_ACTIVE_OBJECT_important; 2 | 3 | /** 4 | * 方法请求对象执行的工作者线程, 5 | * 该线程与主线程(或其他方法调用线程)不属于同一线程, 6 | * 并行地执行方法请求 7 | */ 8 | public class SchedulerThread extends Thread{ 9 | 10 | private final ActivationQueue activationQueue; 11 | 12 | public SchedulerThread(ActivationQueue activationQueue) { 13 | this.activationQueue = activationQueue; 14 | } 15 | 16 | public void invoke(MethodRequest request){ 17 | this.activationQueue.put(request); 18 | } 19 | 20 | @Override 21 | public void run() { 22 | while (true){ 23 | try { 24 | Thread.sleep(1_000); 25 | } catch (InterruptedException e) { 26 | e.printStackTrace(); 27 | } 28 | activationQueue.take().execute(); 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/com/chao/concurrency_basic/chapter9/note.txt: -------------------------------------------------------------------------------- 1 | 1.普通的单个生产者-单个消费者模型在代码实现时,使用wait()和notify()时无问题,但是使用相同的代码在多生产者-多消费者的情境下,可能会出现多个线程同时等待的情况,因为JVM的实现中,可能对notify()唤醒的是哪一个线程没有做出明确规定,就可能导致所有线程同时处于wait状态,无死锁程序却无法继续运行的情况就此产生 2 | 3 | 2.某个线程调用wait()方法时,处于blocked状态的该线程放弃了它所持有的锁,直到其他线程使用notify()或notifyAll()时可能将其唤醒,那么它将重新持有这个锁,并且唤醒该线程的其他线程所持有的锁只应该是该线程的监管对象 4 | 5 | 3.调用了wait()方法相当于wait(0),0代表forever,直到其他线程将其唤醒,另一个方法是wait(long mills),表示该线程在等待mills毫秒后,自己将被唤醒,处于runnable状态,等待CPU的资源使用 6 | 7 | 4.wait()方法被建议在循环中使用 8 | synchronized (obj) { 9 | while (<condition does not hold>) 10 | obj.wait(); 11 | ... // Perform action appropriate to condition 12 | } 13 | 14 | 5.sleep()和wait()的区别 15 | sleep()是Thread的方法,wait()是Object的方法 16 | sleep()不会释放对象锁monitor(LOCK),但是wait()会释放对象锁并且将这个对象放入等待队列 17 | sleep()不需要依靠对象锁,但wait()需要 18 | sleep()不需要被唤醒,而wait()需要 -------------------------------------------------------------------------------- /src/main/java/com/chao/design_pattern/chapter5_SINGLE_THREADED_EXECUTION/Gate.java: -------------------------------------------------------------------------------- 1 | package com.chao.design_pattern.chapter5_SINGLE_THREADED_EXECUTION; 2 | 3 | public class Gate { 4 | private int count; 5 | private String name; 6 | private String address; 7 | 8 | /** 9 | * sharedResource 10 | * add a lock 11 | * 12 | * @param name 13 | * @param address 14 | */ 15 | public synchronized void pass(String name, String address) { 16 | count++; 17 | this.name = name; 18 | this.address = address; 19 | verify(); 20 | } 21 | 22 | private void verify() { 23 | if (name.charAt(0) != address.charAt(0)) { 24 | System.out.println("*******BROKEN*******" + toString()); 25 | } 26 | } 27 | 28 | // sharedResource 29 | public synchronized String toString() { 30 | return "No." + count + " " + this.name + " " + this.address; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/com/chao/design_pattern/chapter18_ACTIVE_OBJECT_important/Servant.java: -------------------------------------------------------------------------------- 1 | package com.chao.design_pattern.chapter18_ACTIVE_OBJECT_important; 2 | 3 | /** 4 | * 方法调用的真正执行者线程, 5 | * 实现了ActiveObject中的方法 6 | */ 7 | class Servant implements ActiveObject { 8 | @Override 9 | public Result makeString(int count, char fillChar) { 10 | char[] buf = new char[count]; 11 | for (int i = 0; i < count; i++) { 12 | buf[i] = fillChar; 13 | try { 14 | Thread.sleep(10); 15 | } catch (InterruptedException e) { 16 | e.printStackTrace(); 17 | } 18 | } 19 | return new RealResult(new String(buf)); 20 | } 21 | 22 | @Override 23 | public void displayString(String text) { 24 | try { 25 | System.out.println("Display: " + text); 26 | Thread.sleep(10); 27 | } catch (InterruptedException e) { 28 | e.printStackTrace(); 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/com/chao/design_pattern/chapter11/ActionContext.java: -------------------------------------------------------------------------------- 1 | package com.chao.design_pattern.chapter11; 2 | 3 | 4 | /** 5 | * 利用ThreadLocal的键值对映射,将线程及其对应的值保存起来, 6 | * 需要时直接通过ThreadLocal直接获取线程对应的值, 7 | * 而不需要一个线程在执行多个对象的方法(多个方法需要的参数相同)时传参, 8 | * 这样可以有效地将线程隔离开来,互不干扰取值 9 | */ 10 | public class ActionContext { 11 | public static final ThreadLocal threadLocal = new ThreadLocal(){ 12 | @Override 13 | public void set(Context context) { 14 | super.set(context); 15 | } 16 | }; 17 | 18 | private ActionContext(){} 19 | 20 | private static class ContextHolder{ 21 | private static ActionContext actionContext = new ActionContext(); 22 | } 23 | 24 | public static ActionContext getActionContext(){ 25 | return ContextHolder.actionContext; 26 | } 27 | 28 | public Context getContext(){ 29 | return threadLocal.get(); 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/com/chao/concurrency_basic/chapter3/CreateThread.java: -------------------------------------------------------------------------------- 1 | package com.chao.concurrency_basic.chapter3; 2 | 3 | public class CreateThread { 4 | public static void main(String[] args) { 5 | Thread t1 = new Thread(); 6 | Thread t2 = new Thread(){ 7 | @Override 8 | public void run() { 9 | System.out.println("==================="); 10 | } 11 | }; 12 | t1.start(); 13 | t2.start(); 14 | System.out.println(t1.getName()); 15 | System.out.println(t2.getName()); 16 | 17 | // 取名之后不会调用nextThreadID() 18 | Thread t3 = new Thread("MyName"); 19 | Thread t4 = new Thread(()-> System.out.println("Runnable....")); 20 | 21 | System.out.println(t3.getName()); 22 | System.out.println(t4.getName()); 23 | 24 | Thread t5 = new Thread(()-> System.out.println("Runnable 5:" + Thread.currentThread().getName()),"Runnable Thread"); 25 | t5.start(); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | concurrency 8 | threadStudy 9 | 1.0-SNAPSHOT 10 | 11 | 12 | 13 | org.apache.maven.plugins 14 | maven-compiler-plugin 15 | 16 | 8 17 | 8 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /src/main/java/com/chao/concurrency_basic/chapter2/tax/TaxCalculator.java: -------------------------------------------------------------------------------- 1 | package com.chao.concurrency_basic.chapter2.tax; 2 | 3 | public class TaxCalculator { 4 | // 工资 5 | private final double salary; 6 | // 奖金 7 | private final double bonus; 8 | 9 | private CalculatorStrategy calculatorStrategy; 10 | 11 | public TaxCalculator(double salary, double bonus) { 12 | this.salary = salary; 13 | this.bonus = bonus; 14 | } 15 | 16 | protected double calcTax(){ 17 | return calculatorStrategy.calculate(salary,bonus); 18 | } 19 | 20 | public double calculate(){ 21 | return this.calcTax(); 22 | } 23 | 24 | public double getSalary() { 25 | return salary; 26 | } 27 | 28 | public double getBonus() { 29 | return bonus; 30 | } 31 | 32 | public void setCalculatorStrategy(CalculatorStrategy calculatorStrategy) { 33 | this.calculatorStrategy = calculatorStrategy; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/main/java/com/chao/concurrency_basic/chapter6/ThreadCloseForce.java: -------------------------------------------------------------------------------- 1 | package com.chao.concurrency_basic.chapter6; 2 | 3 | /** 4 | * 线程强制结束示例 5 | * 6 | * 由于线程被阻塞住,导致以下2种情况中的一种 7 | * 信号量检测 或 Thread.interrupted()方法无法使用 8 | * 这时候需要强制将线程结束 9 | */ 10 | public class ThreadCloseForce { 11 | 12 | public static void main(String[] args) { 13 | ThreadService service = new ThreadService(); 14 | long start = System.currentTimeMillis(); 15 | service.execute(()->{ 16 | // 该情况表示线程被阻塞,或是执行时间过长 17 | /* while (true){ 18 | 19 | }*/ 20 | 21 | // 该情况表示线程被结束时在指定时间之内就可以结束,而不必等待指定时间的大小 22 | try { 23 | Thread.sleep(5000); 24 | } catch (InterruptedException e) { 25 | e.printStackTrace(); 26 | } 27 | 28 | }); 29 | service.shutdown(10000); 30 | long end = System.currentTimeMillis(); 31 | // 计算线程执行时间 32 | System.out.println(end - start); 33 | 34 | 35 | } 36 | } 37 | 38 | -------------------------------------------------------------------------------- /src/main/java/com/chao/concurrency_basic/chapter13_SIMPLE_THREAD_POOL/Test.java: -------------------------------------------------------------------------------- 1 | package com.chao.concurrency_basic.chapter13_SIMPLE_THREAD_POOL; 2 | 3 | import java.util.Optional; 4 | import java.util.stream.IntStream; 5 | 6 | public class Test { 7 | 8 | public static void main(String[] args) { 9 | SimpleThreadPool simpleThreadPool = new SimpleThreadPool(); 10 | IntStream.range(0,20) 11 | .forEach(i->simpleThreadPool.submit(()->{ 12 | Optional.of("The task " + i + " is served by " + Thread.currentThread().getName() + " and start.") 13 | .ifPresent(System.out::println); 14 | try { 15 | Thread.sleep(1_000); 16 | } catch (InterruptedException e) { 17 | e.printStackTrace(); 18 | } 19 | Optional.of("The task " + i + " is served by " + Thread.currentThread().getName() + " and finished.") 20 | .ifPresent(System.out::println); 21 | })); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/com/chao/concurrency_basic/chapter7/SynchronizedThis.java: -------------------------------------------------------------------------------- 1 | package com.chao.concurrency_basic.chapter7; 2 | 3 | public class SynchronizedThis { 4 | 5 | public static void main(String[] args) { 6 | ThisLock lock = new ThisLock(); 7 | /** 8 | * 这里线程T1先获得了锁,执行了m1方法, 9 | * 之后线程T2才获得锁,执行m2方法 10 | */ 11 | new Thread(lock::m1,"T1").start(); 12 | new Thread(lock::m2,"T2").start(); 13 | } 14 | } 15 | 16 | class ThisLock{ 17 | public synchronized void m1(){ 18 | try { 19 | System.out.println(Thread.currentThread().getName()); 20 | Thread.sleep(10_000); 21 | } catch (InterruptedException e) { 22 | e.printStackTrace(); 23 | } 24 | } 25 | 26 | public synchronized void m2(){ 27 | try { 28 | System.out.println(Thread.currentThread().getName()); 29 | Thread.sleep(10_000); 30 | } catch (InterruptedException e) { 31 | e.printStackTrace(); 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/com/chao/concurrency_basic/chapter3/CreateThread2.java: -------------------------------------------------------------------------------- 1 | package com.chao.concurrency_basic.chapter3; 2 | 3 | import java.util.Arrays; 4 | 5 | public class CreateThread2 { 6 | public static void main(String[] args) { 7 | Thread t = new Thread(()->{ 8 | try { 9 | Thread.sleep(1000); 10 | } catch (InterruptedException e) { 11 | e.printStackTrace(); 12 | } 13 | }); 14 | t.start(); 15 | // System.out.println(t.getThreadGroup()); 16 | // System.out.println(Thread.currentThread().getName()); 17 | // System.out.println(Thread.currentThread().getThreadGroup()); 18 | 19 | ThreadGroup threadGroup = Thread.currentThread().getThreadGroup(); 20 | System.out.println(threadGroup.activeCount()); 21 | 22 | Thread[] threads = new Thread[threadGroup.activeCount()]; 23 | threadGroup.enumerate(threads); 24 | Arrays.asList(threads).forEach(System.out::println); 25 | 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/com/chao/design_pattern/chapter17_WORKER_THREAD/TransportThread.java: -------------------------------------------------------------------------------- 1 | package com.chao.design_pattern.chapter17_WORKER_THREAD; 2 | 3 | import java.util.Random; 4 | 5 | public class TransportThread extends Thread { 6 | private String name; 7 | private final Channel channel; 8 | private final Random random = new Random(System.currentTimeMillis()); 9 | 10 | public TransportThread(String name, Channel channel) { 11 | this.name = name; 12 | this.channel = channel; 13 | } 14 | 15 | @Override 16 | public void run() { 17 | while (true) { 18 | String msg = String.valueOf(random.nextInt(100)); 19 | Request request = new Request(msg); 20 | channel.put(request); 21 | System.out.println(name + " put the msg -> " + msg); 22 | try { 23 | Thread.sleep(random.nextInt(1_000)); 24 | } catch (InterruptedException e) { 25 | e.printStackTrace(); 26 | } 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/com/chao/concurrency_basic/chapter9/ProduceConsumerVersion1/ProduceConsumer1.java: -------------------------------------------------------------------------------- 1 | package com.chao.concurrency_basic.chapter9.ProduceConsumerVersion1; 2 | 3 | public class ProduceConsumer1 { 4 | private int i = 1; 5 | private final Object LOCK = new Object(); 6 | 7 | private void produce(){ 8 | synchronized (LOCK){ 9 | System.out.println("P->"+i); 10 | } 11 | } private void consumer(){ 12 | synchronized (LOCK){ 13 | System.out.println("C->"+i); 14 | } 15 | } 16 | 17 | public static void main(String[] args) { 18 | ProduceConsumer1 p = new ProduceConsumer1(); 19 | 20 | new Thread("P"){ 21 | @Override 22 | public void run() { 23 | while (true){ 24 | p.produce(); 25 | } 26 | } 27 | }.start(); 28 | 29 | new Thread("C"){ 30 | @Override 31 | public void run() { 32 | while (true){ 33 | p.consumer(); 34 | } 35 | } 36 | }.start(); 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/com/chao/design_pattern/chapter13_PRODUCER_CONSUMER/ProducerThread.java: -------------------------------------------------------------------------------- 1 | package com.chao.design_pattern.chapter13_PRODUCER_CONSUMER; 2 | 3 | import java.util.Random; 4 | 5 | public class ProducerThread extends Thread{ 6 | private MessageQueue queue; 7 | private String name; 8 | private String msg; 9 | 10 | private static final Random random = new Random(); 11 | 12 | public ProducerThread(MessageQueue queue, String name,String msg) { 13 | super(name); 14 | this.queue = queue; 15 | this.msg = msg; 16 | } 17 | 18 | @Override 19 | public void run() { 20 | while (true){ 21 | Message message = new Message(msg); 22 | queue.put(message); 23 | System.out.println("ProducerThread-" + Thread.currentThread().getName() + " put message is " + message.getMsg()); 24 | try { 25 | Thread.sleep(random.nextInt(1000)); 26 | } catch (InterruptedException e) { 27 | break; 28 | } 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/com/chao/concurrency_basic/chapter5/ThreadJoin.java: -------------------------------------------------------------------------------- 1 | package com.chao.concurrency_basic.chapter5; 2 | 3 | import java.util.Optional; 4 | import java.util.stream.IntStream; 5 | 6 | public class ThreadJoin { 7 | 8 | public static void main(String[] args) throws InterruptedException { 9 | Thread t1 = new Thread(()->{ 10 | IntStream.range(1,1000).forEach(i-> System.out.println(Thread.currentThread().getName() + "->" + i)); 11 | }); 12 | Thread t2 = new Thread(()->{ 13 | IntStream.range(1,1000).forEach(i-> System.out.println(Thread.currentThread().getName() + "->" + i)); 14 | }); 15 | t1.start(); 16 | t2.start(); 17 | t1.join(); 18 | t2.join(); 19 | 20 | Optional.of("All of tasks finish done.").ifPresent(System.out::println); 21 | 22 | // main线程等待上面两个线程结束后才开始执行注释下方的工作;而线程t1和t2是并行执行的 23 | IntStream.range(1,1000).forEach(i-> System.out.println(Thread.currentThread().getName() + "->" + i)); 24 | 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/com/chao/concurrency_basic/chapter5/ThreadJoin2.java: -------------------------------------------------------------------------------- 1 | package com.chao.concurrency_basic.chapter5; 2 | 3 | import java.util.Optional; 4 | import java.util.stream.IntStream; 5 | 6 | public class ThreadJoin2 { 7 | public static void main(String[] args) throws InterruptedException { 8 | Thread t1 = new Thread(()->{ 9 | try { 10 | System.out.println("Thread t is running"); 11 | Thread.sleep(10_000); 12 | System.out.println("Thread t is done"); 13 | } catch (InterruptedException e) { 14 | e.printStackTrace(); 15 | } 16 | }); 17 | t1.start(); 18 | t1.join(100,10); 19 | 20 | Optional.of("All of tasks finish done.").ifPresent(System.out::println); 21 | 22 | // main线程等待线程t1最多100毫秒10纳秒,如果这个时间内t1的工作没有完成,那么main线程开始工作 23 | IntStream.range(1,1000).forEach(i-> System.out.println(Thread.currentThread().getName() + "->" + i)); 24 | 25 | // main线程虽然已经结束(在t1休眠的10秒内),但是由于t1属于活动的线程,所以要等待t1结束程序才会结束 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/com/chao/design_pattern/chapter15_THREAD_PER_MESSAGE/MessageHandle.java: -------------------------------------------------------------------------------- 1 | package com.chao.design_pattern.chapter15_THREAD_PER_MESSAGE; 2 | 3 | import java.util.Random; 4 | import java.util.concurrent.ExecutorService; 5 | import java.util.concurrent.Executors; 6 | 7 | public class MessageHandle { 8 | private final ExecutorService executor = Executors.newFixedThreadPool(5); 9 | private static final Random random = new Random(System.currentTimeMillis()); 10 | 11 | public void request(Message message){ 12 | executor.execute(()->{ 13 | String msg = message.getMsg(); 14 | System.out.println(Thread.currentThread().getName() + " get msg is " + msg); 15 | try { 16 | Thread.sleep(random.nextInt(1_000)); 17 | } catch (InterruptedException e) { 18 | e.printStackTrace(); 19 | } 20 | }); 21 | } 22 | 23 | public void shutdown(){ 24 | 25 | // 调用了shutdown()方法后,不等待线程执行任务完成,立即关闭线程池 26 | // 原因未知 27 | executor.shutdown(); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/com/chao/design_pattern/chapter18_ACTIVE_OBJECT_important/ActiveObjectProxy.java: -------------------------------------------------------------------------------- 1 | package com.chao.design_pattern.chapter18_ACTIVE_OBJECT_important; 2 | 3 | class ActiveObjectProxy implements ActiveObject { 4 | private final SchedulerThread schedulerThread; 5 | private final Servant servant; 6 | 7 | public ActiveObjectProxy(SchedulerThread schedulerThread, Servant servant) { 8 | this.schedulerThread = schedulerThread; 9 | this.servant = servant; 10 | } 11 | 12 | /** 13 | * 两个方法调用都将被包装为方法请求对象 14 | * 立即返回FutureResult对象,并行地执行 15 | */ 16 | @Override 17 | public Result makeString(int count, char fillChar) { 18 | FutureResult futureResult = new FutureResult(); 19 | schedulerThread.invoke(new MakeStringRequest(servant, futureResult, count, fillChar)); 20 | return futureResult; 21 | } 22 | 23 | @Override 24 | public void displayString(String text) { 25 | this.schedulerThread.invoke(new DisplayStringRequest(servant, text)); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/com/chao/_self/connection_pool/ConnectionDriver.java: -------------------------------------------------------------------------------- 1 | package com.chao._self.connection_pool; 2 | 3 | import java.lang.reflect.InvocationHandler; 4 | import java.lang.reflect.Method; 5 | import java.lang.reflect.Proxy; 6 | import java.sql.Connection; 7 | import java.util.concurrent.TimeUnit; 8 | 9 | /** 10 | * Description: 11 | * 12 | * @author W.Chao 13 | * @date 2019/8/21 16:11 14 | **/ 15 | public class ConnectionDriver { 16 | public static final Connection createConnection() { 17 | return (Connection) Proxy.newProxyInstance(Connection.class.getClassLoader(), 18 | new Class[]{Connection.class}, new ConnectionHandler()); 19 | } 20 | 21 | private static class ConnectionHandler implements InvocationHandler { 22 | @Override 23 | public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { 24 | if (method.getName().equals("commit")) { 25 | TimeUnit.SECONDS.sleep(10); 26 | } 27 | return null; 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/com/chao/design_pattern/chapter18_ACTIVE_OBJECT_important/MakerClientThread.java: -------------------------------------------------------------------------------- 1 | package com.chao.design_pattern.chapter18_ACTIVE_OBJECT_important; 2 | 3 | public class MakerClientThread extends Thread { 4 | private final ActiveObject activeObject; 5 | private final char fillChar; 6 | 7 | public MakerClientThread(String name, ActiveObject activeObject) { 8 | super(name); 9 | this.activeObject = activeObject; 10 | this.fillChar = name.charAt(0); 11 | } 12 | 13 | @Override 14 | public void run() { 15 | try { 16 | for (int i = 0; true; i++) { 17 | /** 18 | * 通过proxy进行方法调用 19 | * 返回的result是FutureResult对象 20 | */ 21 | Result result = activeObject.makeString(i + 1, fillChar); 22 | Thread.sleep(100); 23 | String value = (String) result.getResultValue(); 24 | System.out.println(Thread.currentThread().getName() + ":value=" + value); 25 | } 26 | } catch (InterruptedException e) { 27 | e.printStackTrace(); 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/com/chao/concurrency_basic/chapter11/CaptureThreadRuntimeException.java: -------------------------------------------------------------------------------- 1 | package com.chao.concurrency_basic.chapter11; 2 | 3 | public class CaptureThreadRuntimeException { 4 | public static void main(String[] args) { 5 | /** 6 | * 添加运行时钩子程序,当抛出运行时异常时钩子程序启动, 7 | * 并执行一些钩子程序中定义的函数或实现, 8 | * 钩子程序在抛出异常或程序被人为终止时(使用kill process)会被调用 9 | */ 10 | Runtime.getRuntime().addShutdownHook(new Thread(()->{ 11 | System.out.println("will be shutdown"); 12 | // other more method... 13 | notifyAndPrint(); 14 | })); 15 | 16 | int i = 0; 17 | while (true){ 18 | try { 19 | Thread.sleep(1_000); 20 | System.out.println("I am working..."); 21 | } catch (InterruptedException e) { 22 | e.printStackTrace(); 23 | } 24 | i++; 25 | if(i>3){ 26 | throw new RuntimeException("error"); 27 | } 28 | 29 | } 30 | } 31 | 32 | private static void notifyAndPrint() { 33 | System.out.println("will release resources of socket, file and connector.."); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/main/java/com/chao/design_pattern/chapter12_BALKING/BalkingData.java: -------------------------------------------------------------------------------- 1 | package com.chao.design_pattern.chapter12_BALKING; 2 | 3 | import java.io.FileNotFoundException; 4 | import java.io.PrintWriter; 5 | 6 | public class BalkingData { 7 | private String fileName; 8 | private String content; 9 | private boolean changed; 10 | 11 | public BalkingData(String fileName, String content) { 12 | this.fileName = fileName; 13 | this.content = content; 14 | this.changed = true; 15 | } 16 | 17 | public void change(String content){ 18 | this.content = content; 19 | this.changed = true; 20 | } 21 | 22 | public void save(){ 23 | if(!changed){ 24 | return; 25 | } 26 | doSave(); 27 | } 28 | 29 | private void doSave() { 30 | try (PrintWriter printWriter = new PrintWriter(fileName)) { 31 | printWriter.print(content); 32 | printWriter.flush(); 33 | }catch (FileNotFoundException e) { 34 | e.printStackTrace(); 35 | } 36 | System.out.println("The file has saved."); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/com/chao/design_pattern/chapter9/RequestServer.java: -------------------------------------------------------------------------------- 1 | package com.chao.design_pattern.chapter9; 2 | 3 | import java.util.LinkedList; 4 | import java.util.Random; 5 | 6 | public class RequestServer extends Thread { 7 | private final RequestQueue queue; 8 | private final Random random; 9 | private volatile boolean closed = false; 10 | 11 | public RequestServer(RequestQueue queue) { 12 | this.queue = queue; 13 | this.random = new Random(); 14 | } 15 | 16 | @Override 17 | public void run() { 18 | while (!closed) { 19 | Request request = queue.popRequest(); 20 | // 被中断取到的请求为null 21 | if (null == request) { 22 | continue; 23 | } 24 | System.out.println("Server -> " + request.getValue()); 25 | try { 26 | Thread.sleep(random.nextInt(1000)); 27 | } catch (InterruptedException e) { 28 | System.out.println("The server is closed"); 29 | break; 30 | } 31 | } 32 | } 33 | 34 | public void close() { 35 | this.closed = true; 36 | this.interrupt(); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/com/chao/design_pattern/chapter6_READ_WRITE_LOCK/WriteWorker.java: -------------------------------------------------------------------------------- 1 | package com.chao.design_pattern.chapter6_READ_WRITE_LOCK; 2 | 3 | public class WriteWorker extends Thread { 4 | private SharedData sharedData; 5 | private String string; 6 | private int index = 0; 7 | 8 | public WriteWorker(SharedData sharedData, String name, String string) { 9 | super(name); 10 | this.sharedData = sharedData; 11 | this.string = string; 12 | } 13 | 14 | @Override 15 | public void run() { 16 | 17 | try { 18 | while (true) { 19 | char c = string.charAt(nextIndex()); 20 | sharedData.write(c); 21 | System.out.println("The write thread [" + Thread.currentThread().getName() + "] write a character[" + c + "]"); 22 | Thread.sleep(50); 23 | } 24 | } catch (InterruptedException e) { 25 | e.printStackTrace(); 26 | } 27 | } 28 | 29 | private int nextIndex() { 30 | index++; 31 | if (index > string.length() - 1) { 32 | index = 0; 33 | } 34 | return index; 35 | } 36 | 37 | 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/com/chao/design_pattern/chapter14_CUSTOM_COUNT_DOWN_LATCH/CustomCountDown.java: -------------------------------------------------------------------------------- 1 | package com.chao.design_pattern.chapter14_CUSTOM_COUNT_DOWN_LATCH; 2 | 3 | import java.util.Random; 4 | import java.util.concurrent.CountDownLatch; 5 | import java.util.stream.IntStream; 6 | 7 | public class CustomCountDown { 8 | private static Random random = new Random(); 9 | 10 | public static void main(String[] args) throws InterruptedException { 11 | final CountDown countDownLatch = new CountDown(5); 12 | System.out.println("多线程任务开始..."); 13 | IntStream.rangeClosed(1,5).forEach(i-> new Thread(()-> { 14 | System.out.println(Thread.currentThread().getName() + " is working"); 15 | try { 16 | Thread.sleep(random.nextInt(1000)); 17 | } catch (InterruptedException e) { 18 | e.printStackTrace(); 19 | } 20 | countDownLatch.cut(); 21 | }).start()); 22 | 23 | countDownLatch.await(); 24 | System.out.println("多线程任务结束,执行其他任务"); 25 | System.out.println("................"); 26 | System.out.println("Finished."); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/com/chao/_self/semaphore/SemaphoreTest.java: -------------------------------------------------------------------------------- 1 | package com.chao._self.semaphore; 2 | 3 | import java.util.concurrent.Executor; 4 | import java.util.concurrent.Executors; 5 | import java.util.concurrent.Semaphore; 6 | import java.util.concurrent.TimeUnit; 7 | 8 | /** 9 | * Description: 10 | * 11 | * @author W.Chao 12 | * @date 2019/9/2 18:52 13 | **/ 14 | public class SemaphoreTest { 15 | private static final int THREAD_COUNT = 30; 16 | private static Executor serviceThreadPool = Executors.newFixedThreadPool(THREAD_COUNT); 17 | 18 | private static Semaphore semaphore = new Semaphore(10); 19 | 20 | public static void main(String[] args) { 21 | for (int i = 0; i < THREAD_COUNT; i++) { 22 | serviceThreadPool.execute(()->{ 23 | try { 24 | semaphore.acquire(); 25 | System.out.println(Thread.currentThread().getName() + " save data"); 26 | TimeUnit.SECONDS.sleep(2); 27 | semaphore.release(); 28 | } catch (InterruptedException e) { 29 | e.printStackTrace(); 30 | } 31 | }); 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/com/chao/design_pattern/chapter3/VolatileTest.java: -------------------------------------------------------------------------------- 1 | package com.chao.design_pattern.chapter3; 2 | 3 | /** 4 | * volatile:保证内存可见性和有序性 5 | */ 6 | public class VolatileTest { 7 | private volatile static int INIT_VALUE = 0; 8 | 9 | private final static int MAX_LIMIT = 5; 10 | 11 | public static void main(String[] args) { 12 | new Thread(()->{ 13 | int localValue = INIT_VALUE; 14 | while (localValue < MAX_LIMIT){ 15 | if(localValue != INIT_VALUE){ 16 | System.out.printf("The value is [%d]\n",INIT_VALUE); 17 | localValue = INIT_VALUE; 18 | } 19 | } 20 | },"READER").start(); 21 | 22 | new Thread(()->{ 23 | int localValue = INIT_VALUE; 24 | while (INIT_VALUE < MAX_LIMIT){ 25 | if(localValue == INIT_VALUE){ 26 | System.out.printf("Update the value to [%d]\n",++localValue); 27 | INIT_VALUE = localValue; 28 | } 29 | try { 30 | Thread.sleep(100); 31 | } catch (InterruptedException e) { 32 | e.printStackTrace(); 33 | } 34 | } 35 | },"WRITER").start(); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/com/chao/design_pattern/chapter14_CUSTOM_COUNT_DOWN_LATCH/JDKCountDown.java: -------------------------------------------------------------------------------- 1 | package com.chao.design_pattern.chapter14_CUSTOM_COUNT_DOWN_LATCH; 2 | 3 | import java.util.Random; 4 | import java.util.concurrent.CountDownLatch; 5 | import java.util.stream.IntStream; 6 | 7 | public class JDKCountDown { 8 | private static Random random = new Random(); 9 | 10 | public static void main(String[] args) throws InterruptedException { 11 | final CountDownLatch countDownLatch = new CountDownLatch(5); 12 | System.out.println("多线程任务开始..."); 13 | IntStream.rangeClosed(1,5).forEach(i-> new Thread(()-> { 14 | System.out.println(Thread.currentThread().getName() + " is working"); 15 | try { 16 | Thread.sleep(random.nextInt(1000)); 17 | } catch (InterruptedException e) { 18 | e.printStackTrace(); 19 | } 20 | countDownLatch.countDown(); 21 | }).start()); 22 | 23 | countDownLatch.await(); 24 | System.out.println("多线程任务结束,执行其他任务"); 25 | System.out.println("................"); 26 | System.out.println("Finished."); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/com/chao/concurrency_basic/chapter10_CUSTOM_LOCK/LockTest.java: -------------------------------------------------------------------------------- 1 | package com.chao.concurrency_basic.chapter10_CUSTOM_LOCK; 2 | 3 | import java.util.Optional; 4 | import java.util.stream.Stream; 5 | 6 | public class LockTest { 7 | private static final BooleanLock LOCK = new BooleanLock(); 8 | 9 | public static void main(String[] args) { 10 | Stream.of("T1","T2","T3","T4") 11 | .forEach(name->{ 12 | new Thread(()->{ 13 | try { 14 | LOCK.lock(); 15 | Optional.of(Thread.currentThread().getName() + " get the lock") 16 | .ifPresent(System.out::println); 17 | System.out.println(LOCK.getBlockedCollection()); 18 | Thread.sleep(5_000); 19 | } 20 | // catch (Lock.TimeoutException e) { 21 | // Optional.of(Thread.currentThread().getName() + " Timeout") 22 | // .ifPresent(System.out::println); 23 | // } 24 | catch (InterruptedException e) { 25 | e.printStackTrace(); 26 | } finally { 27 | LOCK.unlock(); 28 | } 29 | },name).start(); 30 | }); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/com/chao/concurrency_basic/chapter13_SIMPLE_THREAD_POOL/activeThreadTest.java: -------------------------------------------------------------------------------- 1 | package com.chao.concurrency_basic.chapter13_SIMPLE_THREAD_POOL; 2 | 3 | public class activeThreadTest { 4 | private static volatile int seq = 0; 5 | private static final Object LOCK = new Object(); 6 | public static void main(String[] args) throws InterruptedException { 7 | ThreadGroup tg = new ThreadGroup("TG"); 8 | for(int i = 0;i<5;i++){ 9 | Thread t = new Thread(tg,new Integer(seq++).toString()){ 10 | @Override 11 | public void run() { 12 | synchronized (LOCK){ 13 | try { 14 | LOCK.wait(); 15 | } catch (InterruptedException e) { 16 | e.printStackTrace(); 17 | } 18 | } 19 | } 20 | }; 21 | t.start(); 22 | } 23 | 24 | for(int i = 0;i<5;i++){ 25 | Thread t = new Thread(tg,new Integer(seq++).toString()){ 26 | @Override 27 | public void run() { 28 | while (true){} 29 | } 30 | }; 31 | t.start(); 32 | } 33 | 34 | Thread.sleep(100); 35 | System.out.println(tg.activeCount()); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/com/chao/concurrency_basic/chapter3/CreateThread3.java: -------------------------------------------------------------------------------- 1 | package com.chao.concurrency_basic.chapter3; 2 | 3 | public class CreateThread3 { 4 | 5 | public static int counter = 0; 6 | 7 | public static void main(String[] args) { 8 | Thread t1 = new Thread(){ 9 | @Override 10 | public void run() { 11 | try{ 12 | add(0); 13 | }catch (Error e){ 14 | // StackOverflowError 15 | e.printStackTrace(); 16 | // output: 20662 17 | System.out.println(counter); 18 | } 19 | } 20 | 21 | private void add(int i) { 22 | ++counter; 23 | add(i+1); 24 | } 25 | }; 26 | 27 | t1.start(); 28 | 29 | 30 | Thread t2 = new Thread(null, new Runnable() { 31 | @Override 32 | public void run() { 33 | try{ 34 | add(0); 35 | }catch (Error e){ 36 | // StackOverflowError 37 | e.printStackTrace(); 38 | // output: 1026837 39 | System.out.println(counter); 40 | } 41 | } 42 | private void add(int i) { 43 | ++counter; 44 | add(i+1); 45 | } 46 | }, "test", 1 << 24); 47 | 48 | t2.start(); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/main/java/com/chao/concurrency_basic/chapter7/SynchronizedRunnable.java: -------------------------------------------------------------------------------- 1 | package com.chao.concurrency_basic.chapter7; 2 | 3 | public class SynchronizedRunnable implements Runnable { 4 | private int index = 1; 5 | private final static int MAX = 500; 6 | 7 | public void run() { 8 | while (true){ 9 | /*if(index > MAX) 10 | break; 11 | try { 12 | Thread.sleep(5); 13 | } catch (InterruptedException e) { 14 | e.printStackTrace(); 15 | } 16 | System.out.println(Thread.currentThread() + "的号码是" + (index++));*/ 17 | 18 | if(ticket()){ 19 | break; 20 | } 21 | 22 | } 23 | } 24 | 25 | private boolean ticket(){ 26 | synchronized (this){ 27 | // 读取index 28 | if(index > MAX) 29 | return true; 30 | try { 31 | Thread.sleep(5); 32 | } catch (InterruptedException e) { 33 | e.printStackTrace(); 34 | } 35 | // index++ -> index = index + 1 36 | // 1. 读取index 37 | // 2. index = index + 1 38 | // 3. 将新index返回 39 | System.out.println(Thread.currentThread() + "的号码是" + (index++)); 40 | } 41 | return false; 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /src/main/java/com/chao/design_pattern/chapter16_TWO_PHASE_TERMINATE/custom_test/Terminator.java: -------------------------------------------------------------------------------- 1 | package com.chao.design_pattern.chapter16_TWO_PHASE_TERMINATE.custom_test; 2 | 3 | public class Terminator extends Thread { 4 | private int number; 5 | private volatile boolean interrupt; 6 | 7 | public Terminator(){ 8 | this.interrupt = false; 9 | } 10 | 11 | @Override 12 | public void run() { 13 | try { 14 | while (!interrupt){ 15 | System.out.println("The number is " + number++); 16 | Thread.sleep(100); 17 | } 18 | } catch (InterruptedException e) { 19 | System.out.println("The worker thread is interrupted..."); 20 | }finally { 21 | doSave(); 22 | } 23 | } 24 | 25 | private void doSave() { 26 | System.out.println("Terminator is saving..."); 27 | try { 28 | Thread.sleep(1_000); 29 | } catch (InterruptedException e) { 30 | e.printStackTrace(); 31 | } 32 | System.out.println("Terminator has saved..."); 33 | } 34 | 35 | public boolean isInterrupt() { 36 | return interrupt; 37 | } 38 | 39 | public void terminate(){ 40 | this.interrupt = true; 41 | this.interrupt(); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/main/java/com/chao/design_pattern/chapter18_ACTIVE_OBJECT_important/ActivationQueue.java: -------------------------------------------------------------------------------- 1 | package com.chao.design_pattern.chapter18_ACTIVE_OBJECT_important; 2 | 3 | import java.util.LinkedList; 4 | 5 | /** 6 | * 方法请求对象的缓冲区 7 | * 使用生产者-消费者模式 8 | * 再进行存取时需要锁串行执行 9 | */ 10 | public class ActivationQueue { 11 | 12 | private final static int MAX_METHOD_REQUEST_SIZE = 100; 13 | 14 | private final LinkedList methodRequests = new LinkedList<>(); 15 | 16 | 17 | public synchronized void put(MethodRequest request){ 18 | while (methodRequests.size() >= MAX_METHOD_REQUEST_SIZE){ 19 | try { 20 | this.wait(); 21 | } catch (InterruptedException e) { 22 | e.printStackTrace(); 23 | } 24 | } 25 | this.methodRequests.addLast(request); 26 | this.notifyAll(); 27 | } 28 | 29 | public synchronized MethodRequest take(){ 30 | while (methodRequests.isEmpty()){ 31 | try { 32 | this.wait(); 33 | } catch (InterruptedException e) { 34 | e.printStackTrace(); 35 | } 36 | } 37 | MethodRequest request = methodRequests.removeFirst(); 38 | this.notifyAll(); 39 | return request; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/main/java/com/chao/concurrency_basic/chapter9/differenceOfWaitAndSleep/DifferenceOfWaitAndSleep.java: -------------------------------------------------------------------------------- 1 | package com.chao.concurrency_basic.chapter9.differenceOfWaitAndSleep; 2 | 3 | public class DifferenceOfWaitAndSleep { 4 | private static Object LOCK = new Object(); 5 | 6 | public static void main(String[] args) { 7 | /*1. sleep()是Thread的方法,wait()是Object的方法 8 | 2. sleep()不会释放对象锁monitor(LOCK),但是wait()会释放对象锁并且将这个对象放入等待队列 9 | 3. sleep()不需要依靠对象锁,但wait()需要 10 | 4. sleep()不需要被唤醒,而wait()需要*/ 11 | m1(); 12 | m2(); 13 | } 14 | 15 | public static void m1(){ 16 | try { 17 | Thread.sleep(2_000); 18 | } catch (InterruptedException e) { 19 | e.printStackTrace(); 20 | } 21 | } 22 | public static void m2(){ 23 | synchronized (LOCK){ 24 | try { 25 | LOCK.wait(); 26 | } catch (InterruptedException e) { 27 | e.printStackTrace(); 28 | } 29 | } 30 | 31 | /** 32 | * 33 | * output:Exception in thread "main" java.lang.IllegalMonitorStateException 34 | */ 35 | /*try { 36 | LOCK.wait(); 37 | } catch (InterruptedException e) { 38 | e.printStackTrace(); 39 | }*/ 40 | } 41 | 42 | 43 | } 44 | -------------------------------------------------------------------------------- /src/main/java/com/chao/concurrency_basic/chapter7/note.txt: -------------------------------------------------------------------------------- 1 | 1.synchronized关键字的作用 参看Java基础中的内容 2 | 3 | 2.假设一个类中有两个方法m1和m2同时被synchronized关键字修饰,那么两个线程t1和t2分别调用这两个方法时,当一个线程获得锁执行方法,另一个线程则无法获得锁去执行另一个方法,因为这两个被synchronized修饰的方法的锁是相同的,是this锁;即两个线程不能同时获得一把锁 4 | public class SynchronizedThis { 5 | public static void main(String[] args) { 6 | ThisLock lock = new ThisLock(); 7 | /** 8 | * 这里线程T1先获得了锁,执行了m1方法, 9 | * 之后线程T2才获得锁,执行m2方法 10 | */ 11 | new Thread(lock::m1,"T1").start(); 12 | new Thread(lock::m2,"T2").start(); 13 | } 14 | } 15 | 16 | class ThisLock{ 17 | public synchronized void m1(){ 18 | try { 19 | System.out.println(Thread.currentThread().getName()); 20 | Thread.sleep(10_000); 21 | } catch (InterruptedException e) { 22 | e.printStackTrace(); 23 | } 24 | } 25 | 26 | public synchronized void m2(){ 27 | try { 28 | System.out.println(Thread.currentThread().getName()); 29 | Thread.sleep(10_000); 30 | } catch (InterruptedException e) { 31 | e.printStackTrace(); 32 | } 33 | } 34 | } 35 | 36 | 3.假设synchronized修饰的是静态方法,那么此时的锁是属于类的静态锁,即类名.class,理由同上 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | -------------------------------------------------------------------------------- /src/main/java/com/chao/_self/exchanger/ExchangerTest.java: -------------------------------------------------------------------------------- 1 | package com.chao._self.exchanger; 2 | 3 | import java.util.concurrent.Exchanger; 4 | import java.util.concurrent.Executor; 5 | import java.util.concurrent.Executors; 6 | 7 | /** 8 | * Description: 9 | * 10 | * @author W.Chao 11 | * @date 2019/9/2 19:13 12 | **/ 13 | public class ExchangerTest { 14 | private static final Exchanger exchanger = new Exchanger<>(); 15 | private static Executor executor = Executors.newFixedThreadPool(2); 16 | 17 | public static void main(String[] args) { 18 | executor.execute(() -> { 19 | String A = "银行流水A"; 20 | try { 21 | String exchangeData = exchanger.exchange(null); 22 | System.out.println("A收到数据是:"+ exchangeData); 23 | } catch (InterruptedException e) { 24 | e.printStackTrace(); 25 | } 26 | }); 27 | 28 | executor.execute(() -> { 29 | String B = "银行流水B"; 30 | try { 31 | String exchangeData = exchanger.exchange(B); 32 | System.out.println("A和B的数据是否一致:" + exchangeData.equals(B) + 33 | "\ncurrent B = " + B + "\ncurrent A = " + exchangeData); 34 | } catch (InterruptedException e) { 35 | e.printStackTrace(); 36 | } 37 | }); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/com/chao/design_pattern/chapter13_PRODUCER_CONSUMER/MessageQueue.java: -------------------------------------------------------------------------------- 1 | package com.chao.design_pattern.chapter13_PRODUCER_CONSUMER; 2 | 3 | import java.util.LinkedList; 4 | 5 | public class MessageQueue { 6 | private final LinkedList queue = new LinkedList<>(); 7 | private final int limit; 8 | 9 | private static final int DEFAULT_MAX_LIMIT = 100; 10 | 11 | public MessageQueue() { 12 | this(DEFAULT_MAX_LIMIT); 13 | } 14 | 15 | public MessageQueue(int limit) { 16 | this.limit = limit; 17 | } 18 | 19 | public void put(Message message) { 20 | synchronized (queue){ 21 | while (queue.size() > limit) { 22 | try { 23 | queue.wait(); 24 | } catch (InterruptedException e) { 25 | e.printStackTrace(); 26 | } 27 | } 28 | queue.addLast(message); 29 | queue.notifyAll(); 30 | } 31 | } 32 | 33 | public Message take() { 34 | synchronized (queue){ 35 | while (queue.isEmpty()) { 36 | try { 37 | queue.wait(); 38 | } catch (InterruptedException e) { 39 | e.printStackTrace(); 40 | } 41 | } 42 | Message message = queue.removeFirst(); 43 | queue.notifyAll(); 44 | return message; 45 | } 46 | } 47 | 48 | } 49 | -------------------------------------------------------------------------------- /src/main/java/com/chao/design_pattern/chapter16_TWO_PHASE_TERMINATE/test/ClientHandle.java: -------------------------------------------------------------------------------- 1 | package com.chao.design_pattern.chapter16_TWO_PHASE_TERMINATE.test; 2 | 3 | import java.io.*; 4 | import java.net.Socket; 5 | 6 | public class ClientHandle implements Runnable { 7 | private Socket socket; 8 | 9 | public ClientHandle(Socket socket) { 10 | this.socket = socket; 11 | } 12 | 13 | @Override 14 | public void run() { 15 | try (OutputStream outputStream = socket.getOutputStream(); 16 | InputStream inputStream = socket.getInputStream(); 17 | BufferedReader br = new BufferedReader(new InputStreamReader(inputStream)); 18 | PrintWriter pw = new PrintWriter(outputStream)) { 19 | while (true) { 20 | String msg = br.readLine(); 21 | if ("quit".equals(msg)) { 22 | break; 23 | } 24 | System.out.println("Client send message > " + msg); 25 | pw.print(msg + "\n"); 26 | pw.flush(); 27 | } 28 | } catch (IOException e) { 29 | e.printStackTrace(); 30 | }finally { 31 | doClose(); 32 | } 33 | } 34 | 35 | private void doClose() { 36 | try { 37 | socket.close(); 38 | } catch (IOException e) { 39 | e.printStackTrace(); 40 | } 41 | } 42 | 43 | 44 | } 45 | -------------------------------------------------------------------------------- /src/main/java/com/chao/concurrency_basic/chapter6/note.txt: -------------------------------------------------------------------------------- 1 | 1.线程使用interrupt()方法来中断线程,真正意思为给这个线程打上“中断”的标记,让这个线程能够被捕获中断异常InterruptedException 2 | 3 | 2.Thread类中有成员方法isInterrupted()和静态方法Thread.interrupted()可以测试当前线程是否被中断,返回true或false;静态方法的interrupted()的底层同样是调用了isInterrupted()方法,而这样是为了适应不同的需求而存在的方法 4 | public static boolean interrupted() { 5 | return currentThread().isInterrupted(true); 6 | } 7 | 8 | 3.interrupted()方法可以中断join()方法,使用的时候,若是用其他线程来中断某个线程,那么中断时要判断正确的、需要被中断的线程,否则无法中断 9 | Thread t = new Thread(){ 10 | @Override 11 | public void run() { 12 | while (true){} 13 | } 14 | }; 15 | 16 | t.start(); 17 | Thread main = Thread.currentThread(); 18 | Thread t2 = new Thread(){ 19 | @Override 20 | public void run() { 21 | try { 22 | Thread.sleep(100); 23 | } catch (InterruptedException e) { 24 | e.printStackTrace(); 25 | } 26 | 27 | main.interrupt(); 28 | System.out.println("interrupt"); 29 | } 30 | }; 31 | 32 | t2.start(); 33 | 34 | try { 35 | t.join(); 36 | } catch (InterruptedException e) { 37 | e.printStackTrace(); 38 | } 39 | 40 | 4.结束线程的3种方法 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | -------------------------------------------------------------------------------- /src/main/java/com/chao/design_pattern/chapter8_FUTURE/FutureTest.java: -------------------------------------------------------------------------------- 1 | package com.chao.design_pattern.chapter8_FUTURE; 2 | 3 | public class FutureTest { 4 | public static void main(String[] args) throws InterruptedException { 5 | FutureService futureService = new FutureService(); 6 | Future future = futureService.submit(() -> { 7 | // 给FutureTask call()方法的任务 8 | try { 9 | Thread.sleep(10_000); 10 | } catch (InterruptedException e) { 11 | e.printStackTrace(); 12 | } 13 | return "FINISHED"; 14 | }); 15 | 16 | System.out.println("=========="); 17 | System.out.println("do other thing"); 18 | System.out.println("=========="); 19 | /** 20 | * 假设主线程需要做的事情约为15秒,那么15秒后, 21 | * 分配给futureService做的任务(10秒)已经完成, 22 | * 主线程取走结果不花费多余的时间(比如等待10秒) 23 | * 24 | * 如果主线程需要做的事情只有1秒,那么1秒后, 25 | * 分配给分配给futureService做的任务(10秒)还需要9秒才能完成, 26 | * 那么主线程取走结果(调用AsynFuture的get())需要等待9秒 27 | * 28 | * 总体上来说,这样两个线程做任务可以实现并行,减少时间等待 29 | */ 30 | Thread.sleep(1_000); 31 | long startTime = System.currentTimeMillis(); 32 | System.out.println(future.get()); 33 | long endTime = System.currentTimeMillis(); 34 | System.out.println("取出结果花费的时间:" + (endTime - startTime)); 35 | System.out.println("=========="); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/com/chao/design_pattern/chapter10/ThreadLocalTest.java: -------------------------------------------------------------------------------- 1 | package com.chao.design_pattern.chapter10; 2 | 3 | import java.util.Random; 4 | 5 | public class ThreadLocalTest { 6 | private static ThreadLocal threadLocal = new ThreadLocal(); 7 | 8 | private static Random random = new Random(System.currentTimeMillis()); 9 | 10 | // JVM start main thread 11 | public static void main(String[] args) throws InterruptedException { 12 | Thread t1 = new Thread(() -> { 13 | threadLocal.set("Thread-T1"); 14 | try { 15 | Thread.sleep(random.nextInt(1000)); 16 | System.out.println(Thread.currentThread().getName() + " " + threadLocal.get()); 17 | } catch (InterruptedException e) { 18 | e.printStackTrace(); 19 | } 20 | }); 21 | 22 | Thread t2 = new Thread(() -> { 23 | threadLocal.set("Thread-T2"); 24 | try { 25 | Thread.sleep(random.nextInt(1000)); 26 | System.out.println(Thread.currentThread().getName() + " " + threadLocal.get()); 27 | } catch (InterruptedException e) { 28 | e.printStackTrace(); 29 | } 30 | }); 31 | 32 | t1.start(); 33 | t2.start(); 34 | t1.join(); 35 | t2.join(); 36 | System.out.println("========================"); 37 | System.out.println(Thread.currentThread().getName() + " " + threadLocal.get()); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/com/chao/concurrency_basic/chapter1/TryConcurrency.java: -------------------------------------------------------------------------------- 1 | package com.chao.concurrency_basic.chapter1; 2 | 3 | public class TryConcurrency { 4 | 5 | public static void main(String[] args) { 6 | new Thread("read-thread"){ 7 | @Override 8 | public void run() { 9 | readFromDataBase(); 10 | } 11 | }.start(); 12 | 13 | new Thread("write-thread"){ 14 | @Override 15 | public void run() { 16 | writeDataToFile(); 17 | } 18 | }.start(); 19 | } 20 | 21 | private static void readFromDataBase(){ 22 | // read data from database and handle it 23 | try { 24 | print("Begin read data from db."); 25 | Thread.sleep(1000 * 10L); 26 | print("Read data done and start handle it."); 27 | } catch (InterruptedException e) { 28 | e.printStackTrace(); 29 | } 30 | print("The data handle finish and successfully. -read"); 31 | } 32 | 33 | private static void writeDataToFile(){ 34 | // write data to file 35 | try { 36 | print("Begin write data to file."); 37 | Thread.sleep(1000 * 10L); 38 | print("Write data done and start handle it."); 39 | } catch (InterruptedException e) { 40 | e.printStackTrace(); 41 | } 42 | print("The data handle finish and successfully. -write"); 43 | } 44 | 45 | private static void print(String msg){ 46 | System.out.println(msg); 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /src/main/java/com/chao/concurrency_basic/chapter13_SIMPLE_THREAD_POOL/Test2.java: -------------------------------------------------------------------------------- 1 | package com.chao.concurrency_basic.chapter13_SIMPLE_THREAD_POOL; 2 | 3 | import java.util.Optional; 4 | import java.util.stream.IntStream; 5 | 6 | public class Test2 { 7 | public static void main(String[] args) throws InterruptedException { 8 | SimpleThreadPool2 simpleThreadPool = new SimpleThreadPool2(); 9 | IntStream.range(0,20) 10 | .forEach(i->simpleThreadPool.submit(()->{ 11 | Optional.of("The task " + i + " is served by " + Thread.currentThread().getName() + " and start.") 12 | .ifPresent(System.out::println); 13 | try { 14 | Thread.sleep(1_000); 15 | } catch (InterruptedException e) { 16 | e.printStackTrace(); 17 | } 18 | Optional.of("The task " + i + " is served by " + Thread.currentThread().getName() + " and finished.") 19 | .ifPresent(System.out::println); 20 | })); 21 | 22 | simpleThreadPool.shutdown(); 23 | Thread.sleep(20); 24 | // output: Exception in thread "main" java.lang.RuntimeException: The Simple-Thread already destroyed. 25 | simpleThreadPool.shutdown(); 26 | // output: Exception in thread "main" java.lang.RuntimeException: The Simple-Thread has destroyed and not allow to submit task. 27 | simpleThreadPool.submit(()-> System.out.println("==========")); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/com/chao/design_pattern/chapter4_OBSERVER/multithread_Observer_to_moniror_the_Thread_lifecycle/ObservableRunnable.java: -------------------------------------------------------------------------------- 1 | package com.chao.design_pattern.chapter4_OBSERVER.multithread_Observer_to_moniror_the_Thread_lifecycle; 2 | 3 | /** 4 | * 被监控的线程对象:主题 5 | */ 6 | public abstract class ObservableRunnable implements Runnable{ 7 | private ObserverLifeCycleListener listener; 8 | 9 | // 注册监管者 10 | public ObservableRunnable(ObserverLifeCycleListener listener) { 11 | this.listener = listener; 12 | } 13 | 14 | // 使用监管者的onEvent()方法来进行通知 15 | public void notifyChange(RunnableEvent event){ 16 | listener.onEvent(event); 17 | } 18 | 19 | public enum RunnableStatus{ 20 | RUNNING,ERROR,DONE 21 | } 22 | 23 | /** 24 | * 线程事件 25 | * 包括线程的状态、当前线程、线程执行时发生的错误 26 | */ 27 | public static class RunnableEvent{ 28 | private final RunnableStatus status; 29 | private final Thread thread; 30 | private final Throwable cause; 31 | 32 | public RunnableEvent(RunnableStatus status, Thread thread, Throwable cause) { 33 | this.status = status; 34 | this.thread = thread; 35 | this.cause = cause; 36 | } 37 | 38 | public RunnableStatus getStatus() { 39 | return status; 40 | } 41 | 42 | public Thread getThread() { 43 | return thread; 44 | } 45 | 46 | public Throwable getCause() { 47 | return cause; 48 | } 49 | } 50 | 51 | } 52 | -------------------------------------------------------------------------------- /src/main/java/com/chao/design_pattern/chapter3/note.txt: -------------------------------------------------------------------------------- 1 | 并发编程中3个比较重要的概念: 2 | 1.原子性:保证一个操作或者个多个操作,要么都成功,要么都失败,中间不能由于任何的因素中断 3 | 2.可见性:一个变量被更新,其它访问这个变量的线程应该得到更新后的变量值(最新变量) 4 | 3.有序性:操作按照一定的顺序执行 5 | 6 | 7 | 8 | Java如何保证上面3种特性的: 9 | 1.原子性:对基本数据类型的变量读取和赋值是保证了原子性的,要么都成功,要么都失败,这些操作不可被中断 10 | 2.可见性(使用volatile关键字保证可见性):被volatile修饰的变量都应该从主存中读取 11 | 3.有序性:(happens-before relationship) 12 | 3.1 代码的执行顺序,编写在前面的发生在编写的后面 13 | 3.2 unlock必须发生在lock之后 14 | 3.3 volatile修饰的变量,对该变量的写操作必须发生在该变量的读操作之前 15 | 3.4 传递规则:操作A先于B,B先于C,那么A肯定先于C 16 | 3.5 线程启动规则:start()方法肯定先于线程run()方法 17 | 3.6 线程中断规则:interrupt这个动作,必须发生在捕获该动作之前 18 | 3.7 对象销毁规则:初始化必须发生在finalize之前 19 | 3.8 线程终结规则:所有的操作都发生在线程死亡之前 20 | 21 | volatile关键字 22 | 一旦一个共享变量被volatile修饰,具备两层语义 23 | 1.保证了不同线程间的可见性 24 | 2.禁止对其进行重排序,也就是保证了有序性 25 | 3.并为保证原子性 26 | 27 | 保证重排序的是不会把后面的指令放到屏障的前面,也不会把前面的放到后面 28 | 强制对缓存的修改操作立即写入主存 29 | 如果是写操作,它会导致其他CPU中的缓存失效(其他线程中的缓存失效) 30 | 31 | volatile的使用场景 32 | 1.状态量标记 33 | volatile boolean start = true; 34 | while(start){ 35 | // ... 36 | } 37 | 38 | void close(){ 39 | start = false; 40 | } 41 | 42 | 2.保证屏障前后的一致性 43 | volatile boolean init; 44 | 45 | ------Thread -1-------- 46 | 47 | obj = careateObje(); 1. 48 | init = true; 2. <----屏障 49 | 50 | ------Thread -2-------- 51 | while(!init){ 52 | sleep(); 53 | } 54 | 55 | useTheObj(); 56 | ------ End ---------- 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | -------------------------------------------------------------------------------- /src/main/java/com/chao/_self/twins_lock/TestTwinsLock.java: -------------------------------------------------------------------------------- 1 | package com.chao._self.twins_lock; 2 | 3 | 4 | import java.util.concurrent.TimeUnit; 5 | import java.util.concurrent.locks.Lock; 6 | import java.util.concurrent.locks.ReentrantLock; 7 | import java.util.stream.IntStream; 8 | 9 | /** 10 | * Description: 11 | * 12 | * @author W.Chao 13 | * @date 2019/8/30 14:32 14 | **/ 15 | public class TestTwinsLock { 16 | public static void main(String[] args) { 17 | final Lock twinsLock = new TwinsLock(); 18 | class Worker extends Thread{ 19 | public Worker(String name){ 20 | super(name); 21 | } 22 | 23 | @Override 24 | public void run() { 25 | while (true){ 26 | twinsLock.lock(); 27 | try{ 28 | TimeUnit.SECONDS.sleep(1); 29 | System.out.println(Thread.currentThread().getName()); 30 | TimeUnit.SECONDS.sleep(1); 31 | }catch(Exception e){ 32 | e.printStackTrace(); 33 | }finally { 34 | twinsLock.unlock(); 35 | } 36 | } 37 | } 38 | } 39 | 40 | IntStream.range(0, 10).forEach(i->{ 41 | Worker w = new Worker("TwinsLock-"+i); 42 | w.setDaemon(true); 43 | w.start(); 44 | }); 45 | 46 | for (int i=0;i<10;i++){ 47 | try { 48 | TimeUnit.SECONDS.sleep(1); 49 | } catch (InterruptedException e) { 50 | e.printStackTrace(); 51 | } 52 | System.out.println(); 53 | } 54 | 55 | 56 | ReentrantLock r = new ReentrantLock(); 57 | r.lock(); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/main/java/com/chao/design_pattern/chapter6_READ_WRITE_LOCK/SharedData.java: -------------------------------------------------------------------------------- 1 | package com.chao.design_pattern.chapter6_READ_WRITE_LOCK; 2 | 3 | /** 4 | * 共享数据类:临界区 5 | * 该类中的读、写操作都是线程间遵守读写锁规则的操作, 6 | * 这样可以实现读操作的并行,写操作串行,提高效率 7 | */ 8 | public class SharedData { 9 | private final char[] buffer; 10 | private ReadWriteLock lock; 11 | 12 | public SharedData(int size){ 13 | this(size,true); 14 | } 15 | 16 | public SharedData(int size, boolean prefWrite) { 17 | this.lock = new ReadWriteLock(prefWrite); 18 | this.buffer = new char[size]; 19 | for (int i = 0; i < size; i++) { 20 | buffer[i] = '*'; 21 | } 22 | } 23 | 24 | public String read() throws InterruptedException { 25 | lock.readLock(); 26 | String buf = doRead(); 27 | slowly(100); 28 | lock.readUnlock(); 29 | return buf; 30 | } 31 | 32 | private void slowly(int mills) { 33 | try { 34 | Thread.sleep(mills); 35 | } catch (InterruptedException e) { 36 | e.printStackTrace(); 37 | } 38 | } 39 | 40 | private String doRead() { 41 | char[] newBuf = new char[buffer.length]; 42 | System.arraycopy(buffer, 0, newBuf, 0, buffer.length); 43 | return String.valueOf(newBuf); 44 | } 45 | 46 | public void write(char c) throws InterruptedException { 47 | lock.writeLock(); 48 | doWrite(c); 49 | slowly(5); 50 | lock.writeUnlock(); 51 | } 52 | 53 | private void doWrite(char c) { 54 | for(int i=0;i sheetBankWaterCount = new ConcurrentHashMap<>(); 18 | 19 | private void count() { 20 | for (int i = 0; i < 4; i++) { 21 | // 启动4个线程去模拟计算 22 | executor.execute(() -> { 23 | sheetBankWaterCount.put(Thread.currentThread().getName(), 1); 24 | // 计算完成之后调用await()方法阻塞 25 | try { 26 | cyclicBarrier.await(); 27 | System.out.println(Thread.currentThread().getName()); 28 | } catch (InterruptedException | BrokenBarrierException e) { 29 | e.printStackTrace(); 30 | } 31 | }); 32 | } 33 | } 34 | 35 | @Override 36 | public void run() { 37 | int result = 0; 38 | for (Map.Entry sheet : sheetBankWaterCount.entrySet()) { 39 | result += sheet.getValue(); 40 | } 41 | sheetBankWaterCount.put("result", result); 42 | System.out.println(result); 43 | } 44 | 45 | public static void main(String[] args) { 46 | BankWaterService bankWaterService = new BankWaterService(); 47 | bankWaterService.count(); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/main/java/com/chao/concurrency_basic/chapter5/ThreadJoin3.java: -------------------------------------------------------------------------------- 1 | package com.chao.concurrency_basic.chapter5; 2 | 3 | public class ThreadJoin3 { 4 | 5 | public static void main(String[] args) throws InterruptedException { 6 | long startTime = System.currentTimeMillis(); 7 | Thread t1 = new Thread(new CaptureRunnable("M1",10_000L)); 8 | Thread t2 = new Thread(new CaptureRunnable("M2",30_000L)); 9 | Thread t3 = new Thread(new CaptureRunnable("M3",15_000L)); 10 | 11 | t1.start(); 12 | t2.start(); 13 | t3.start(); 14 | 15 | t1.join(); 16 | t2.join(); 17 | t3.join(); 18 | 19 | long endTime = System.currentTimeMillis(); 20 | System.out.printf("Save data begin timestamp is: %s, end timestamp:%s",startTime,endTime); 21 | System.out.println(); 22 | } 23 | } 24 | 25 | 26 | class CaptureRunnable implements Runnable{ 27 | private String machineName; 28 | private long spendTime; 29 | 30 | public CaptureRunnable(String machineName, long spendTime) { 31 | this.machineName = machineName; 32 | this.spendTime = spendTime; 33 | } 34 | 35 | public void getResult(){ 36 | System.out.println(machineName + "finished."); 37 | } 38 | 39 | @Override 40 | public void run() { 41 | // do something 42 | try { 43 | Thread.sleep(spendTime); 44 | System.out.printf(machineName + " completed data capture timestamp is [%s] and successful.",System.currentTimeMillis()); 45 | System.out.println(); 46 | } catch (InterruptedException e) { 47 | e.printStackTrace(); 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/main/java/com/chao/design_pattern/chapter16_TWO_PHASE_TERMINATE/test/AppServer.java: -------------------------------------------------------------------------------- 1 | package com.chao.design_pattern.chapter16_TWO_PHASE_TERMINATE.test; 2 | 3 | import java.io.IOException; 4 | import java.net.ServerSocket; 5 | import java.net.Socket; 6 | import java.util.concurrent.ExecutorService; 7 | import java.util.concurrent.Executors; 8 | 9 | public class AppServer extends Thread { 10 | private static final int DEFAULT_PORT = 18989; 11 | private ServerSocket serverSocket; 12 | private boolean start; 13 | 14 | private ExecutorService executor = Executors.newFixedThreadPool(10); 15 | 16 | public AppServer() { 17 | this(DEFAULT_PORT); 18 | } 19 | 20 | public AppServer(int port) { 21 | try { 22 | this.serverSocket = new ServerSocket(port); 23 | this.start = true; 24 | } catch (IOException e) { 25 | e.printStackTrace(); 26 | } 27 | } 28 | 29 | @Override 30 | public void run() { 31 | try { 32 | while (start) { 33 | Socket socket = null; 34 | socket = serverSocket.accept(); 35 | if (socket == null) { 36 | continue; 37 | } 38 | executor.submit(new ClientHandle(socket)); 39 | } 40 | } catch (IOException e) { 41 | e.printStackTrace(); 42 | } finally { 43 | doDestroy(); 44 | } 45 | 46 | } 47 | 48 | private void doDestroy() { 49 | try { 50 | serverSocket.close(); 51 | executor.shutdown(); 52 | } catch (IOException e) { 53 | e.printStackTrace(); 54 | } 55 | } 56 | 57 | public void shutdown() { 58 | this.start = false; 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/main/java/com/chao/design_pattern/chapter17_WORKER_THREAD/Channel.java: -------------------------------------------------------------------------------- 1 | package com.chao.design_pattern.chapter17_WORKER_THREAD; 2 | 3 | import java.util.Arrays; 4 | import java.util.LinkedList; 5 | 6 | public class Channel { 7 | private LinkedList RequestQueue; 8 | private WorkerTread[] workerThreads; 9 | private int workerCount; 10 | private int queueMaxCount; 11 | 12 | public Channel(int workerCount) { 13 | this.workerCount = workerCount; 14 | this.RequestQueue = new LinkedList<>(); 15 | this.workerThreads = new WorkerTread[workerCount]; 16 | this.queueMaxCount = 100; 17 | init(); 18 | } 19 | 20 | private void init() { 21 | for (int i = 0; i < workerCount; i++) { 22 | workerThreads[i] = new WorkerTread("Worker Thread-" + i, this); 23 | } 24 | } 25 | 26 | public void startWork() { 27 | Arrays.asList(workerThreads).forEach(WorkerTread::start); 28 | } 29 | 30 | public synchronized void put(Request request){ 31 | while (RequestQueue.size() >= queueMaxCount){ 32 | try { 33 | this.wait(); 34 | } catch (InterruptedException e) { 35 | e.printStackTrace(); 36 | } 37 | } 38 | RequestQueue.addLast(request); 39 | this.notifyAll(); 40 | } 41 | 42 | public synchronized Request take(){ 43 | while (RequestQueue.isEmpty()){ 44 | try { 45 | this.wait(); 46 | } catch (InterruptedException e) { 47 | e.printStackTrace(); 48 | } 49 | } 50 | Request request = RequestQueue.removeFirst(); 51 | this.notifyAll(); 52 | return request; 53 | } 54 | 55 | 56 | } 57 | -------------------------------------------------------------------------------- /src/main/java/com/chao/concurrency_basic/chapter12/ThreadGroupCreate.java: -------------------------------------------------------------------------------- 1 | package com.chao.concurrency_basic.chapter12; 2 | 3 | import java.util.Arrays; 4 | 5 | public class ThreadGroupCreate { 6 | 7 | public static void main(String[] args) throws InterruptedException { 8 | 9 | ThreadGroup tg1 = new ThreadGroup("TG1"); 10 | 11 | Thread t = new Thread(tg1,"t1"){ 12 | @Override 13 | public void run() { 14 | // try { 15 | // Thread.sleep(100_000); 16 | // System.out.println(getThreadGroup().getName()); 17 | // System.out.println(getThreadGroup().getParent().getName()); 18 | // System.out.println(getThreadGroup().getParent().activeCount()); 19 | // } catch (InterruptedException e) { 20 | // e.printStackTrace(); 21 | // } 22 | while (true){ 23 | 24 | } 25 | } 26 | }; 27 | 28 | t.start(); 29 | 30 | // ThreadGroup tg2 = new ThreadGroup(tg1,"TG2"); 31 | // System.out.println(tg2.getName()); 32 | // System.out.println(tg2.getParent().getName()); 33 | // 34 | // 35 | // System.out.println(Thread.currentThread().getName()); 36 | // System.out.println(Thread.currentThread().getThreadGroup().getName()); 37 | 38 | ThreadGroup tg2 = new ThreadGroup("TG2"); 39 | Thread t2 = new Thread(tg2,"t2"){ 40 | @Override 41 | public void run() { 42 | System.out.println(tg1.getName()); 43 | Thread[] threads = new Thread[tg1.activeCount()]; 44 | tg1.enumerate(threads); 45 | Arrays.asList(threads).forEach(System.out::println); 46 | } 47 | }; 48 | 49 | t2.start(); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/main/java/com/chao/concurrency_basic/chapter9/ProduceConsumerVersion2/ProduceConsumer2.java: -------------------------------------------------------------------------------- 1 | package com.chao.concurrency_basic.chapter9.ProduceConsumerVersion2; 2 | 3 | /** 4 | * 这是一个简单的生产者-消费者模型,但 5 | * 在多个生产者-多个消费者情况下会出现问题 6 | */ 7 | public class ProduceConsumer2 { 8 | private int i = 1; 9 | 10 | private final Object LOCK = new Object(); 11 | private volatile boolean isProduced = false; 12 | 13 | private void produce() { 14 | synchronized (LOCK) { 15 | if (isProduced) { 16 | try { 17 | LOCK.wait(); 18 | } catch (InterruptedException e) { 19 | e.printStackTrace(); 20 | } 21 | } else { 22 | // 这里表示i被消费,需要被生产,生产后通知消费者消费 23 | i++; 24 | System.out.println("P->" + i); 25 | isProduced = true; 26 | LOCK.notify(); 27 | } 28 | } 29 | } 30 | 31 | private void consumer(){ 32 | synchronized (LOCK){ 33 | if(isProduced){ 34 | System.out.println("C->"+i); 35 | isProduced = false; 36 | LOCK.notify(); 37 | }else { 38 | // 这里表示i已经消费过了,通知生产者生产 39 | try { 40 | LOCK.wait(); 41 | } catch (InterruptedException e) { 42 | e.printStackTrace(); 43 | } 44 | } 45 | } 46 | } 47 | 48 | public static void main(String[] args) { 49 | ProduceConsumer2 p = new ProduceConsumer2(); 50 | 51 | new Thread("P"){ 52 | @Override 53 | public void run() { 54 | while (true){ 55 | p.produce(); 56 | } 57 | } 58 | }.start(); 59 | 60 | new Thread("C"){ 61 | @Override 62 | public void run() { 63 | while (true){ 64 | p.consumer(); 65 | } 66 | } 67 | }.start(); 68 | } 69 | 70 | } 71 | -------------------------------------------------------------------------------- /src/main/java/com/chao/_self/connection_pool/ConnectionPool.java: -------------------------------------------------------------------------------- 1 | package com.chao._self.connection_pool; 2 | 3 | import java.sql.Connection; 4 | import java.util.LinkedList; 5 | 6 | /** 7 | * Description: 8 | * 9 | * @author W.Chao 10 | * @date 2019/8/21 16:07 11 | **/ 12 | public class ConnectionPool { 13 | private final LinkedList pool = new LinkedList<>(); 14 | 15 | public ConnectionPool(int maxSize) { 16 | if (maxSize > 0) { 17 | for (int i = 0; i < 10; i++) { 18 | pool.addLast(ConnectionDriver.createConnection()); 19 | } 20 | } 21 | } 22 | 23 | public void releaseConnection(Connection connection) { 24 | if (connection != null) { 25 | synchronized (pool) { 26 | pool.addLast(connection); 27 | } 28 | } 29 | } 30 | 31 | /** 32 | * 获取连接 33 | * @param mills 34 | * @return 35 | * @throws InterruptedException 36 | */ 37 | public Connection fetchConnection(long mills) throws InterruptedException { 38 | synchronized (pool) { 39 | //完全超时 40 | if (mills <= 0) { 41 | while (pool.isEmpty()) { 42 | pool.wait(); 43 | } 44 | } else { 45 | long future = System.currentTimeMillis() + mills; 46 | long remaining = mills; 47 | // 连接池空且还有等待的时间,线程继续等待 48 | while (pool.isEmpty() && remaining > 0) { 49 | pool.wait(remaining); 50 | // 等待线程被其他线程唤醒之后要重新计算还能等待的时间 51 | remaining = future - System.currentTimeMillis(); 52 | } 53 | Connection result = null; 54 | if (!pool.isEmpty()) { 55 | result = pool.removeFirst(); 56 | } 57 | return result; 58 | } 59 | } 60 | return null; 61 | } 62 | 63 | 64 | } 65 | -------------------------------------------------------------------------------- /src/main/java/com/chao/design_pattern/chapter4_OBSERVER/multithread_Observer_to_moniror_the_Thread_lifecycle/ObserverLifeCycleListener.java: -------------------------------------------------------------------------------- 1 | package com.chao.design_pattern.chapter4_OBSERVER.multithread_Observer_to_moniror_the_Thread_lifecycle; 2 | 3 | import java.util.List; 4 | 5 | /** 6 | * 线程生命周期的监管者 7 | * 8 | */ 9 | public class ObserverLifeCycleListener implements LifeCycleListener { 10 | private final Object LOCK = new Object(); 11 | 12 | // 为每个线程注册监听者和安排任务 13 | public void concurrentQuery(List ids) { 14 | if (ids == null || ids.isEmpty()) { 15 | return; 16 | } 17 | ids.forEach(id -> new Thread(new ObservableRunnable(this) { 18 | @Override 19 | public void run() { 20 | try { 21 | notifyChange(new RunnableEvent(RunnableStatus.RUNNING, Thread.currentThread(), null)); 22 | System.out.println("Query for the id is " + id); 23 | Thread.sleep(1000); 24 | // int i = 1/0; error status 25 | notifyChange(new RunnableEvent(RunnableStatus.DONE, Thread.currentThread(), null)); 26 | } catch (Exception e) { 27 | notifyChange(new RunnableEvent(RunnableStatus.ERROR, Thread.currentThread(), e)); 28 | } 29 | } 30 | }, id).start()); 31 | } 32 | 33 | // 监管者被通知后,可以通过“主题”传递的信息做一些操作 34 | @Override 35 | public void onEvent(ObservableRunnable.RunnableEvent event) { 36 | synchronized (LOCK) { 37 | System.out.println("The runnable [" + event.getThread().getName() + "] data changed and status is " + event.getStatus()); 38 | if (event.getCause() != null) { 39 | System.out.println("The runnable [" + event.getThread().getName() + "] process failed."); 40 | event.getCause().printStackTrace(); 41 | } 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/main/java/com/chao/design_pattern/chapter6_READ_WRITE_LOCK/ReadWriteLock.java: -------------------------------------------------------------------------------- 1 | package com.chao.design_pattern.chapter6_READ_WRITE_LOCK; 2 | 3 | /*是否进行串行化(加锁)处理[y/n?] 4 | +-------------------------+ 5 | + |READ | WRITE + 6 | +-------------------------+ 7 | + READ | N | Y + 8 | +-------------------------+ 9 | +WRITE | Y | Y + 10 | +-------------------------+*/ 11 | 12 | public class ReadWriteLock { 13 | // 正在读取数据的线程数量 14 | private static int readingReader = 0; 15 | // 等待读取数据的线程数量 16 | private static int waitingReader = 0; 17 | // 正在写入数据的线程数量 18 | private static int writingWriter = 0; 19 | // 等待写入数据的线程数量 20 | private static int waitingWriter = 0; 21 | // 对读写操作的偏好设置 22 | private boolean prefWrite; 23 | 24 | public ReadWriteLock(boolean prefWrite) { 25 | this.prefWrite = prefWrite; 26 | } 27 | 28 | public synchronized void readLock() throws InterruptedException { 29 | try { 30 | waitingReader++; 31 | // 有线程正在对数据写入时,不可读取数据 32 | while (writingWriter > 0 || (prefWrite && writingWriter > 0)) { 33 | wait(); 34 | } 35 | readingReader++; 36 | } finally { 37 | waitingReader--; 38 | } 39 | } 40 | 41 | public synchronized void readUnlock() { 42 | readingReader--; 43 | notifyAll(); 44 | } 45 | 46 | public synchronized void writeLock() throws InterruptedException { 47 | try { 48 | waitingWriter++; 49 | // 有线程正在等待读取或有其他线程正在写入数据时,不可对数据进行写操作 50 | while (waitingReader > 0 || readingReader > 0) { 51 | wait(); 52 | } 53 | } finally { 54 | waitingWriter--; 55 | } 56 | } 57 | 58 | public synchronized void writeUnlock() { 59 | writingWriter--; 60 | notifyAll(); 61 | } 62 | 63 | } 64 | -------------------------------------------------------------------------------- /src/main/java/com/chao/_self/thread_pool/Test3.java: -------------------------------------------------------------------------------- 1 | package com.chao._self.thread_pool; 2 | 3 | import java.util.Optional; 4 | import java.util.stream.IntStream; 5 | 6 | public class Test3 { 7 | public static void main(String[] args) throws InterruptedException { 8 | DefaultThreadPool defaultThreadPool = new DefaultThreadPool<>(); 9 | IntStream.range(0, 30) 10 | .forEach(i -> defaultThreadPool.execute(() -> { 11 | Optional.of("The task " + i + " is served by " + Thread.currentThread().getName() + " and start.") 12 | .ifPresent(System.out::println); 13 | try { 14 | Thread.sleep(3_000); 15 | } catch (InterruptedException e) { 16 | e.printStackTrace(); 17 | } 18 | Optional.of("The task " + i + " is served by " + Thread.currentThread().getName() + " and finished.") 19 | .ifPresent(System.out::println); 20 | Optional.of("Current workers has " + defaultThreadPool.getWorkerNum() + " workers") 21 | .ifPresent(System.out::println); 22 | })); 23 | 24 | Thread.sleep(5_000); 25 | System.out.println("=========================="); 26 | defaultThreadPool.addWorker(10); 27 | 28 | IntStream.range(0, 50) 29 | .forEach(i -> defaultThreadPool.execute(() -> { 30 | Optional.of("The task " + i + " is served by " + Thread.currentThread().getName() + " and start.") 31 | .ifPresent(System.out::println); 32 | try { 33 | Thread.sleep(3_000); 34 | } catch (InterruptedException e) { 35 | e.printStackTrace(); 36 | } 37 | Optional.of("The task " + i + " is served by " + Thread.currentThread().getName() + " and finished.") 38 | .ifPresent(System.out::println); 39 | })); 40 | 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/main/java/com/chao/concurrency_basic/chapter6/ThreadInterrupt.java: -------------------------------------------------------------------------------- 1 | package com.chao.concurrency_basic.chapter6; 2 | 3 | public class ThreadInterrupt { 4 | private static final Object MONITOR = new Object(); 5 | 6 | public static void main(String[] args){ 7 | /*Thread t = new Thread(){ 8 | @Override 9 | public void run() { 10 | while (true){ 11 | synchronized (MONITOR){ 12 | try { 13 | Thread.sleep(10); 14 | } catch (InterruptedException e) { 15 | System.out.println("Interrupt..."); 16 | break; 17 | } 18 | } 19 | } 20 | } 21 | }; 22 | 23 | t.start(); 24 | Thread.sleep(1000); 25 | 26 | System.out.println(t.isInterrupted()); 27 | t.interrupt(); 28 | System.out.println(t.isInterrupted());*/ 29 | 30 | /*Thread t = new Thread(()->{ 31 | while (true){ 32 | synchronized (MONITOR){ 33 | try { 34 | MONITOR.wait(10); 35 | } catch (InterruptedException e) { 36 | System.out.println(Thread.interrupted()); 37 | break; 38 | } 39 | } 40 | } 41 | });*/ 42 | 43 | 44 | Thread t = new Thread(){ 45 | @Override 46 | public void run() { 47 | while (true){ 48 | 49 | } 50 | } 51 | }; 52 | 53 | t.start(); 54 | Thread main = Thread.currentThread(); 55 | Thread t2 = new Thread(){ 56 | @Override 57 | public void run() { 58 | try { 59 | Thread.sleep(100); 60 | } catch (InterruptedException e) { 61 | e.printStackTrace(); 62 | } 63 | 64 | main.interrupt(); 65 | System.out.println("interrupt"); 66 | } 67 | }; 68 | 69 | t2.start(); 70 | 71 | try { 72 | t.join(); 73 | } catch (InterruptedException e) { 74 | e.printStackTrace(); 75 | } 76 | 77 | 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /src/main/java/com/chao/concurrency_basic/chapter13_SIMPLE_THREAD_POOL/Test3.java: -------------------------------------------------------------------------------- 1 | package com.chao.concurrency_basic.chapter13_SIMPLE_THREAD_POOL; 2 | 3 | import java.util.Optional; 4 | import java.util.stream.IntStream; 5 | 6 | public class Test3 { 7 | public static void main(String[] args) throws InterruptedException { 8 | SimpleThreadPool3 simpleThreadPool = new SimpleThreadPool3(); 9 | IntStream.range(0,30) 10 | .forEach(i->simpleThreadPool.submit(()->{ 11 | Optional.of("The task " + i + " is served by " + Thread.currentThread().getName() + " and start.") 12 | .ifPresent(System.out::println); 13 | try { 14 | Thread.sleep(3_000); 15 | } catch (InterruptedException e) { 16 | e.printStackTrace(); 17 | } 18 | Optional.of("The task " + i + " is served by " + Thread.currentThread().getName() + " and finished.") 19 | .ifPresent(System.out::println); 20 | })); 21 | 22 | Thread.sleep(5_000); 23 | System.out.println("=========================="); 24 | 25 | 26 | IntStream.range(0,10) 27 | .forEach(i->simpleThreadPool.submit(()->{ 28 | Optional.of("The task " + i + " is served by " + Thread.currentThread().getName() + " and start.") 29 | .ifPresent(System.out::println); 30 | try { 31 | Thread.sleep(3_000); 32 | } catch (InterruptedException e) { 33 | e.printStackTrace(); 34 | } 35 | Optional.of("The task " + i + " is served by " + Thread.currentThread().getName() + " and finished.") 36 | .ifPresent(System.out::println); 37 | })); 38 | 39 | // 测试:最后在1个线程工作时,是否能维持最小线程数在线程池中, 40 | // 这个测试不喝shutdown()一起调用 41 | // simpleThreadPool.submit(()->{ 42 | // while (true){ 43 | // 44 | // } 45 | // }); 46 | 47 | simpleThreadPool.shutdown(); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/main/java/com/chao/concurrency_basic/chapter6/ThreadService.java: -------------------------------------------------------------------------------- 1 | package com.chao.concurrency_basic.chapter6; 2 | 3 | public class ThreadService { 4 | private Thread executeThread; 5 | private boolean finished = false; 6 | 7 | /** 8 | * 线程执行 9 | * @param task 线程任务 10 | */ 11 | public void execute(Runnable task){ 12 | executeThread = new Thread(() -> { 13 | /** 14 | * 将需要被执行的任务作为该工作线程的守护线程 15 | * 目的是为了当工作线程结束,守护线程的生命周期就结束了 16 | */ 17 | Thread runner = new Thread(task); 18 | runner.setDaemon(true); 19 | 20 | runner.start(); 21 | try { 22 | // 工作线程等待真正的任务线程工作完毕 23 | runner.join(); 24 | // 执行到finished = true说明task完成了 25 | finished = true; 26 | } catch (InterruptedException e) { 27 | // e.printStackTrace(); 28 | } 29 | }); 30 | executeThread.start(); 31 | } 32 | 33 | /** 34 | * 强制结束 35 | * 36 | * @param mills 最长等待时间 37 | */ 38 | public void shutdown(long mills){ 39 | // 方法被调用时间 40 | long currentTime = System.currentTimeMillis(); 41 | /** 42 | * 如果这里while()内的条件为true,表示任务完成, 43 | * 否则任务没有完成,需要被强制结束 44 | * 45 | * 如果在调用此方法时,任务线程已经结束或在最长等待时间内结束了, 46 | * (例如示例中,10秒最长等待时间,而任务线程5秒就结束了) 47 | * 那么,finished会被置为true,那么会跳出循环,工作线程的run()方法也执行完成,那么作为守护线程的任务也被关闭 48 | */ 49 | while (!finished){ 50 | // 任务未完成,每次循环都检测是否超过最长等待时间 51 | if((System.currentTimeMillis() - currentTime) >= mills){ 52 | System.out.println("任务超时,需要结束"); 53 | executeThread.interrupt(); 54 | break; 55 | } 56 | 57 | // 用于捕获工作线程是否被中断 58 | try { 59 | executeThread.sleep(1); 60 | } catch (InterruptedException e) { 61 | System.out.println("执行线程被中断"); 62 | break; 63 | } 64 | } 65 | // 重置 66 | // 若是任务在调用结束线程前完成(finished为true),那么重置即可 67 | finished = false; 68 | } 69 | 70 | } 71 | -------------------------------------------------------------------------------- /src/main/java/com/chao/_self/condition_await_signal/BoundedQueue.java: -------------------------------------------------------------------------------- 1 | package com.chao._self.condition_await_signal; 2 | 3 | import java.util.concurrent.atomic.AtomicIntegerFieldUpdater; 4 | import java.util.concurrent.atomic.AtomicReference; 5 | import java.util.concurrent.locks.Condition; 6 | import java.util.concurrent.locks.Lock; 7 | import java.util.concurrent.locks.ReentrantLock; 8 | 9 | /** 10 | * Description: 构造一个有界队列,线程安全地获取锁并添加到队列中, 11 | * 当队列满时,需要添加元素的线程将被阻塞,直到队列有“空位”时线程被唤醒, 12 | * 继续尝试添加元素到队列中 13 | * 14 | * @author W.Chao 15 | * @date 2019/8/31 9:57 16 | **/ 17 | public class BoundedQueue { 18 | private Object[] items; 19 | 20 | private int addIndex, removeIndex, count; 21 | 22 | private Lock lock = new ReentrantLock(); 23 | private Condition notFull = lock.newCondition(); 24 | private Condition notEmpty = lock.newCondition(); 25 | 26 | public BoundedQueue(int size) { 27 | items = new Object[size]; 28 | } 29 | 30 | public void add(T t) throws InterruptedException { 31 | lock.lock(); 32 | // 获取到锁之后尝试添加元素 33 | try { 34 | while (count == items.length) { 35 | notFull.await(); 36 | } 37 | items[addIndex] = t; 38 | // 添加的元素为队列最后一个元素时,将添加的下标置为0,循环队列 39 | /*addIndex = (addIndex+1)%items.length*/ 40 | if (++addIndex == items.length) { 41 | addIndex = 0; 42 | } 43 | count++; 44 | notEmpty.signal(); 45 | } finally { 46 | lock.unlock(); 47 | } 48 | } 49 | 50 | public T remove() throws InterruptedException { 51 | lock.lock(); 52 | try { 53 | while (count == 0) { 54 | notEmpty.await(); 55 | } 56 | Object x = items[removeIndex]; 57 | if (++removeIndex == items.length) { 58 | removeIndex = 0; 59 | } 60 | count--; 61 | notFull.signal(); 62 | return (T) x; 63 | } finally { 64 | lock.unlock(); 65 | } 66 | } 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | } 75 | -------------------------------------------------------------------------------- /src/main/java/com/chao/design_pattern/chapter7_IMMUTABLE_DESIGN_PATTERN/note.txt: -------------------------------------------------------------------------------- 1 | 1.不可变对象一定是线程安全的,里面的任何属性或者引用类型的属性都不能被修改 2 | 2.可变对象不一定是不安全的 3 | 4 | 5 | 6 | 定义不可变对象的策略: 7 | 1.不要设置“setter”方法 8 | 2.让所有字段被final和private修饰 9 | 3.不允许创建该不可变对象的类被继承(让类也被final修饰) 10 | 4.如果实例对象中包含可变的对象引用,不要让它们被改变 11 | 4.1不提供改变这些可变对象的方法 12 | 4.2不要共享对可变对象的引用。如有必要,返回可变对象时,创建可变对象的副本,不要将可变对象本身返回 13 | 14 | 15 | 可以通过以下步骤创建一个不可变对象类: 16 | 1.所有字段设置为final private 17 | 2.所有字段的初始化都依靠构造函数来进行 18 | 3.ImmutableRGB类除了基本类型外,仅有一个String的引用类型,但String本身是不可变的(不需要额外的对可变对象引用的保护),如若有其他可变对象引用,那么需要增加保护措施 19 | 4.ImmutableRGB类中没有设置setter,只有getter 20 | 5.提供反转的invert()方法没有返回对象本身,而是返回了一个新的对象 21 | final public class ImmutableRGB { 22 | 23 | // Values must be between 0 and 255. 24 | final private int red; 25 | final private int green; 26 | final private int blue; 27 | final private String name; 28 | 29 | private void check(int red, 30 | int green, 31 | int blue) { 32 | if (red < 0 || red > 255 33 | || green < 0 || green > 255 34 | || blue < 0 || blue > 255) { 35 | throw new IllegalArgumentException(); 36 | } 37 | } 38 | 39 | public ImmutableRGB(int red, 40 | int green, 41 | int blue, 42 | String name) { 43 | check(red, green, blue); 44 | this.red = red; 45 | this.green = green; 46 | this.blue = blue; 47 | this.name = name; 48 | } 49 | 50 | 51 | public int getRGB() { 52 | return ((red << 16) | (green << 8) | blue); 53 | } 54 | 55 | public String getName() { 56 | return name; 57 | } 58 | 59 | public ImmutableRGB invert() { 60 | return new ImmutableRGB(255 - red, 61 | 255 - green, 62 | 255 - blue, 63 | "Inverse of " + name); 64 | } 65 | } -------------------------------------------------------------------------------- /src/main/java/com/chao/design_pattern/chapter2/WaitSet.java: -------------------------------------------------------------------------------- 1 | package com.chao.design_pattern.chapter2; 2 | 3 | import java.util.Optional; 4 | import java.util.stream.IntStream; 5 | 6 | /** 7 | * 1.所有的对象都会有一个wait set,用来存放调用了该对象wait()方法之后进入block状态线程 8 | * 2.线程被notify()之后不一定立即得到执行 9 | * 3.线程从wait set中被唤醒的顺序不一定是FIFO,根据JVM的实现来决定 10 | * 4.线程执行wait()方法之后,会释放所持有的锁,被唤醒之后再一次获取锁,之后从执行wait()方法后的代码继续执行 11 | */ 12 | public class WaitSet { 13 | 14 | private static final Object LOCK = new Object(); 15 | 16 | private static void work(){ 17 | synchronized (LOCK){ 18 | System.out.println("Begin..."); 19 | 20 | try { 21 | System.out.println("Thread will coming..."); 22 | LOCK.wait(); 23 | } catch (InterruptedException e) { 24 | e.printStackTrace(); 25 | } 26 | System.out.println("Thread will out..."); 27 | } 28 | } 29 | 30 | public static void main(String[] args) { 31 | /*IntStream.rangeClosed(1,10).forEach(i-> new Thread(String.valueOf(i)){ 32 | @Override 33 | public void run() { 34 | synchronized (LOCK){ 35 | Optional.of(Thread.currentThread().getName()+" into wait set.").ifPresent(System.out::println); 36 | try { 37 | LOCK.wait(); 38 | } catch (InterruptedException e) { 39 | e.printStackTrace(); 40 | } 41 | Optional.of(Thread.currentThread().getName()+" out wait set.").ifPresent(System.out::println); 42 | } 43 | } 44 | }.start()); 45 | 46 | try { 47 | Thread.sleep(5_000); 48 | } catch (InterruptedException e) { 49 | e.printStackTrace(); 50 | } 51 | 52 | IntStream.rangeClosed(1,3).forEach(i-> new Thread(String.valueOf(i)){ 53 | @Override 54 | public void run() { 55 | synchronized (LOCK){ 56 | LOCK.notify(); 57 | try { 58 | Thread.sleep(100); 59 | } catch (InterruptedException e) { 60 | e.printStackTrace(); 61 | } 62 | } 63 | } 64 | }.start());*/ 65 | new Thread(WaitSet::work).start(); 66 | try { 67 | Thread.sleep(1000); 68 | } catch (InterruptedException e) { 69 | e.printStackTrace(); 70 | } 71 | synchronized (LOCK){ 72 | LOCK.notify(); 73 | } 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /src/main/java/com/chao/_self/self_lock/Mutex.java: -------------------------------------------------------------------------------- 1 | package com.chao._self.self_lock; 2 | 3 | import java.util.concurrent.TimeUnit; 4 | import java.util.concurrent.locks.AbstractQueuedSynchronizer; 5 | import java.util.concurrent.locks.Condition; 6 | import java.util.concurrent.locks.Lock; 7 | 8 | /** 9 | * Description: 10 | * 11 | * @author W.Chao 12 | * @date 2019/8/22 14:48 13 | **/ 14 | public class Mutex implements Lock { 15 | /** 16 | * 推荐使用的子类 17 | */ 18 | private static class Sync extends AbstractQueuedSynchronizer { 19 | // 当状态为0的时候上锁 20 | @Override 21 | protected boolean tryAcquire(int arg) { 22 | if (compareAndSetState(0, 1)) { 23 | setExclusiveOwnerThread(Thread.currentThread()); 24 | return true; 25 | } 26 | return false; 27 | } 28 | 29 | // 释放锁,将状态设置为0 30 | @Override 31 | protected boolean tryRelease(int arg) { 32 | if (getState() == 0) { 33 | throw new IllegalMonitorStateException(); 34 | } 35 | setExclusiveOwnerThread(null); 36 | return true; 37 | } 38 | 39 | // 是否处于占用状态 40 | @Override 41 | protected boolean isHeldExclusively() { 42 | return getState() == 1; 43 | } 44 | 45 | Condition newCondition() { 46 | return new ConditionObject(); 47 | } 48 | } 49 | 50 | private final Sync sync = new Sync(); 51 | 52 | @Override 53 | public void lock() { 54 | sync.tryAcquire(1); 55 | } 56 | 57 | @Override 58 | public void lockInterruptibly() throws InterruptedException { 59 | sync.acquireInterruptibly(1); 60 | } 61 | 62 | @Override 63 | public boolean tryLock() { 64 | return sync.tryAcquire(1); 65 | } 66 | 67 | @Override 68 | public boolean tryLock(long time, TimeUnit unit) throws InterruptedException { 69 | return sync.tryAcquireNanos(1, unit.toNanos(time)); 70 | } 71 | 72 | @Override 73 | public void unlock() { 74 | sync.tryRelease(1); 75 | } 76 | 77 | @Override 78 | public Condition newCondition() { 79 | return sync.newCondition(); 80 | } 81 | 82 | public boolean hasQueuedThreads() { 83 | return sync.hasQueuedThreads(); 84 | } 85 | 86 | public boolean isLocked() { 87 | return sync.isHeldExclusively(); 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /src/main/java/com/chao/concurrency_basic/chapter9/ProduceConsumerVersion3/ProduceConsumer3.java: -------------------------------------------------------------------------------- 1 | package com.chao.concurrency_basic.chapter9.ProduceConsumerVersion3; 2 | 3 | import java.util.stream.Stream; 4 | 5 | /** 6 | * 7 | * 8 | */ 9 | public class ProduceConsumer3 { 10 | private int i = 1; 11 | 12 | private final Object LOCK = new Object(); 13 | private volatile boolean isProduced = false; 14 | 15 | private void produce(String p) { 16 | synchronized (LOCK) { 17 | /** 18 | * 生产者检测产品是否被消费 19 | * 没有被消费则一直处于被阻塞状态,直到被消费者唤醒 20 | * 而消费者调用notifyAll()方法时,唤醒哪一个生产者由JVM的实现方法决定 21 | */ 22 | while (isProduced) { 23 | try { 24 | LOCK.wait(); 25 | } catch (InterruptedException e) { 26 | e.printStackTrace(); 27 | } 28 | } 29 | i++; 30 | System.out.println(p+"->" + i); 31 | isProduced = true; 32 | // 将阻塞的所有线程唤醒 33 | LOCK.notifyAll(); 34 | } 35 | } 36 | 37 | 38 | private void consumer(String c) { 39 | synchronized (LOCK) { 40 | /** 41 | * 消费者检测到有可消费的产品就将其消费 42 | * 随后通知生产者进行生产,之后自己进入被阻塞状态 43 | * 直到被其他线程唤醒后再进行检测 44 | */ 45 | while (isProduced) { 46 | System.out.println(c+"->" + i); 47 | isProduced = false; 48 | // 将阻塞的所有线程唤醒 49 | LOCK.notifyAll(); 50 | } 51 | try { 52 | LOCK.wait(); 53 | } catch (InterruptedException e) { 54 | e.printStackTrace(); 55 | } 56 | } 57 | } 58 | 59 | 60 | public static void main(String[] args) { 61 | ProduceConsumer3 p = new ProduceConsumer3(); 62 | Stream.of("P1", "P2").forEach(n -> new Thread(n) { 63 | @Override 64 | public void run() { 65 | while (true) { 66 | p.produce(n); 67 | try { 68 | Thread.sleep(1000); 69 | } catch (InterruptedException e) { 70 | e.printStackTrace(); 71 | } 72 | } 73 | } 74 | }.start()); 75 | 76 | Stream.of("C1", "C2", "C3").forEach(n -> new Thread(n) { 77 | @Override 78 | public void run() { 79 | while (true) { 80 | p.consumer(n); 81 | try { 82 | Thread.sleep(1000); 83 | } catch (InterruptedException e) { 84 | e.printStackTrace(); 85 | } 86 | } 87 | } 88 | }.start()); 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /src/main/java/com/chao/_self/twins_lock/TwinsLock.java: -------------------------------------------------------------------------------- 1 | package com.chao._self.twins_lock; 2 | 3 | import java.util.concurrent.TimeUnit; 4 | import java.util.concurrent.locks.AbstractQueuedSynchronizer; 5 | import java.util.concurrent.locks.Condition; 6 | import java.util.concurrent.locks.Lock; 7 | 8 | /** 9 | * Description:设计一个同步工具:该工具在同一时刻,只允许至多两个线程同时访问,超过两个线程的 10 | * 访问将被阻塞 11 | * 12 | * @author W.Chao 13 | * @date 2019/8/30 14:31 14 | **/ 15 | public class TwinsLock implements Lock { 16 | private static final Sync sync = new Sync(2); 17 | 18 | private static final class Sync extends AbstractQueuedSynchronizer { 19 | Sync(int count) { 20 | if (count <= 0) { 21 | throw new IllegalArgumentException("count must large than zero"); 22 | } 23 | setState(count); 24 | } 25 | 26 | @Override 27 | protected int tryAcquireShared(int reduceCount) { 28 | for (; ; ) { 29 | int current = getState(); 30 | int newCount = current - reduceCount; 31 | if (newCount < 0 || compareAndSetState(current, newCount)) { 32 | return newCount; 33 | } 34 | } 35 | } 36 | 37 | @Override 38 | protected boolean tryReleaseShared(int returnCount) { 39 | for (; ; ) { 40 | int current = getState(); 41 | int newCount = current + returnCount; 42 | if (compareAndSetState(current, newCount)) { 43 | return true; 44 | } 45 | } 46 | } 47 | 48 | @Override 49 | protected boolean isHeldExclusively() { 50 | return getState()==1; 51 | } 52 | 53 | Condition newCondition(){ 54 | return new ConditionObject(); 55 | } 56 | } 57 | 58 | @Override 59 | public void lock() { 60 | sync.acquireShared(1); 61 | } 62 | 63 | @Override 64 | public void lockInterruptibly() throws InterruptedException { 65 | sync.acquireInterruptibly(1); 66 | } 67 | 68 | @Override 69 | public boolean tryLock() { 70 | return false; 71 | } 72 | 73 | @Override 74 | public boolean tryLock(long time, TimeUnit unit) throws InterruptedException { 75 | return false; 76 | } 77 | 78 | @Override 79 | public void unlock() { 80 | sync.releaseShared(1); 81 | } 82 | 83 | @Override 84 | public Condition newCondition() { 85 | return sync.newCondition(); 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /src/main/java/com/chao/concurrency_basic/chapter9/CaptureService.java: -------------------------------------------------------------------------------- 1 | package com.chao.concurrency_basic.chapter9; 2 | 3 | import java.util.ArrayList; 4 | import java.util.LinkedList; 5 | import java.util.Optional; 6 | import java.util.stream.Stream; 7 | 8 | /** 9 | * 需求:多台机器进行数据采集,使用1个线程代表1个机器, 10 | * 同时运行的机器不能超过5个,当其中某一个机器结束工作了, 11 | * 剩余的其他机器能够开始工作,直到所有机器完成工作, 12 | * 结束本次任务 13 | * 要求:综合使用生产者-消费者模型和Java8语法糖 14 | */ 15 | 16 | public class CaptureService { 17 | private static final LinkedList CONTROLS = new LinkedList<>(); 18 | private static final int MAX_MACHINE_COUNT = 5; 19 | 20 | public static void main(String[] args) { 21 | ArrayList machines = new ArrayList<>(); 22 | 23 | Stream.of("M1", "M2", "M3", "M4", "M5", "M6", "M7", "M8", "M9", "M10", "M11", "M12") 24 | .map(CaptureService::createWorkThread) 25 | .forEach(t->{ 26 | t.start(); 27 | machines.add(t); 28 | }); 29 | 30 | machines.forEach(t->{ 31 | try { 32 | // 让main线程等待所有机器工作执行完成 33 | t.join(); 34 | } catch (InterruptedException e) { 35 | e.printStackTrace(); 36 | } 37 | }); 38 | } 39 | 40 | private static Thread createWorkThread(String name) { 41 | return new Thread(() -> { 42 | // 具体工作内容 43 | synchronized (CONTROLS) { 44 | while (CONTROLS.size() > MAX_MACHINE_COUNT) { 45 | try { 46 | CONTROLS.wait(); 47 | } catch (InterruptedException e) { 48 | e.printStackTrace(); 49 | } 50 | } 51 | CONTROLS.addLast(new Control()); 52 | } 53 | 54 | Optional.of("The machine [" + Thread.currentThread().getName() + "] BEGIN to work") 55 | .ifPresent(System.out::println); 56 | Optional.of("The machine [" + Thread.currentThread().getName() + "] is working") 57 | .ifPresent(System.out::println); 58 | 59 | // 模拟工作 60 | try { 61 | Thread.sleep(10_000L); 62 | } catch (InterruptedException e) { 63 | e.printStackTrace(); 64 | } 65 | 66 | // 工作完成 67 | synchronized (CONTROLS) { 68 | CONTROLS.removeFirst(); 69 | // 唤醒其他正在等待的机器 70 | CONTROLS.notifyAll(); 71 | Optional.of("The machine [" + Thread.currentThread().getName() + "] END work") 72 | .ifPresent(System.out::println); 73 | } 74 | }, name); 75 | } 76 | 77 | private static class Control { 78 | } 79 | 80 | } 81 | -------------------------------------------------------------------------------- /src/main/java/com/chao/concurrency_basic/chapter10_CUSTOM_LOCK/BooleanLock.java: -------------------------------------------------------------------------------- 1 | package com.chao.concurrency_basic.chapter10_CUSTOM_LOCK; 2 | 3 | import java.util.Collection; 4 | import java.util.Collections; 5 | import java.util.LinkedList; 6 | import java.util.Optional; 7 | 8 | public class BooleanLock implements Lock{ 9 | private LinkedList CollectionOfBlockedThread = new LinkedList<>(); 10 | 11 | // lockValue is true meant a thread get the lock 12 | // lockValue is false meant the lock is free. (any threads can get the lock) 13 | private boolean lockValue; 14 | private Thread currentThread; 15 | 16 | @Override 17 | public synchronized void lock(){ 18 | while (lockValue){ 19 | try { 20 | // add all blocked thread 21 | CollectionOfBlockedThread.addLast(Thread.currentThread()); 22 | wait(); 23 | } catch (InterruptedException e) { 24 | e.printStackTrace(); 25 | } 26 | } 27 | this.lockValue = true; 28 | CollectionOfBlockedThread.clear(); 29 | this.currentThread = Thread.currentThread(); 30 | } 31 | 32 | @Override 33 | public synchronized void lock(long mills) throws TimeoutException { 34 | if(mills <= 0){ 35 | lock(); 36 | } 37 | long endTime = System.currentTimeMillis() + mills; 38 | long hasRemaining = endTime - System.currentTimeMillis(); 39 | while (lockValue){ 40 | if(hasRemaining <= 0){ 41 | throw new TimeoutException("Timeout Exception"); 42 | }else { 43 | try { 44 | CollectionOfBlockedThread.addLast(Thread.currentThread()); 45 | this.wait(mills); 46 | hasRemaining = endTime - System.currentTimeMillis(); 47 | } catch (InterruptedException e) { 48 | e.printStackTrace(); 49 | } 50 | } 51 | } 52 | this.lockValue = true; 53 | CollectionOfBlockedThread.clear(); 54 | this.currentThread = Thread.currentThread(); 55 | } 56 | 57 | @Override 58 | public synchronized void unlock() { 59 | if(currentThread == Thread.currentThread()){ 60 | Optional.of(Thread.currentThread().getName() + " release the lock") 61 | .ifPresent(System.out::println); 62 | lockValue = false; 63 | notifyAll(); 64 | } 65 | } 66 | 67 | @Override 68 | public Collection getBlockedCollection() { 69 | return Collections.unmodifiableCollection(CollectionOfBlockedThread); 70 | } 71 | 72 | @Override 73 | public int getCollectionOfBlockedThreadSize() { 74 | return CollectionOfBlockedThread.size(); 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /src/main/java/com/chao/_self/readwrite_lock/TestReadWriteLock.java: -------------------------------------------------------------------------------- 1 | package com.chao._self.readwrite_lock; 2 | 3 | import java.util.HashMap; 4 | import java.util.concurrent.TimeUnit; 5 | import java.util.concurrent.locks.Lock; 6 | import java.util.concurrent.locks.ReentrantReadWriteLock; 7 | import java.util.stream.IntStream; 8 | 9 | /** 10 | * Description: 11 | * 12 | * @author W.Chao 13 | * @date 2019/8/30 16:41 14 | **/ 15 | public class TestReadWriteLock { 16 | static final class Cache { 17 | private static HashMap cache = new HashMap<>(); 18 | private static ReentrantReadWriteLock rwl = new ReentrantReadWriteLock(); 19 | private static Lock r = rwl.readLock(); 20 | private static Lock w = rwl.writeLock(); 21 | 22 | public static Object get(String key) { 23 | r.lock(); 24 | try { 25 | String result = cache.get(key); 26 | if (result == null) { 27 | return "error"; 28 | } else { 29 | return result; 30 | } 31 | } finally { 32 | r.unlock(); 33 | } 34 | } 35 | 36 | public static Object put(String key, String value) { 37 | w.lock(); 38 | try { 39 | return cache.put(key, value); 40 | } finally { 41 | w.unlock(); 42 | } 43 | } 44 | 45 | public static void clear() { 46 | w.lock(); 47 | try { 48 | cache.clear(); 49 | } finally { 50 | w.unlock(); 51 | } 52 | } 53 | } 54 | 55 | static class WriteWorker extends Thread { 56 | private int count; 57 | 58 | public WriteWorker(String name, int count) { 59 | super(name); 60 | this.count = count; 61 | } 62 | 63 | @Override 64 | public void run() { 65 | while (true) { 66 | try { 67 | count++; 68 | System.out.println(Thread.currentThread().getName() + "->" + count); 69 | Cache.put("1", String.valueOf(count)); 70 | TimeUnit.SECONDS.sleep(5); 71 | } catch (Exception e) { 72 | e.printStackTrace(); 73 | } 74 | } 75 | } 76 | } 77 | 78 | static class ReadWorker extends Thread { 79 | public ReadWorker(String name) { 80 | super(name); 81 | } 82 | 83 | @Override 84 | public void run() { 85 | while (true) { 86 | try { 87 | System.out.println(Thread.currentThread().getName()+"->"+Cache.get("1")); 88 | TimeUnit.SECONDS.sleep(3); 89 | } catch (Exception e) { 90 | e.printStackTrace(); 91 | } 92 | } 93 | } 94 | } 95 | 96 | public static void main(String[] args) { 97 | 98 | new WriteWorker("Write-Thread-0",0).start(); 99 | 100 | IntStream.range(1, 5).forEach(i -> { 101 | new ReadWorker("Read-Thread-" + i).start(); 102 | }); 103 | } 104 | 105 | } 106 | -------------------------------------------------------------------------------- /src/main/java/com/chao/_self/connection_pool/ConnectionPoolTest.java: -------------------------------------------------------------------------------- 1 | package com.chao._self.connection_pool; 2 | 3 | import java.sql.Connection; 4 | import java.sql.SQLException; 5 | import java.util.concurrent.CountDownLatch; 6 | import java.util.concurrent.atomic.AtomicInteger; 7 | 8 | /** 9 | * Description: 10 | * 11 | * @author W.Chao 12 | * @date 2019/8/21 16:28 13 | **/ 14 | public class ConnectionPoolTest { 15 | private static ConnectionPool pool = new ConnectionPool(10); 16 | // 保证所有ConnectionRunner能够同时开始 17 | private static CountDownLatch start = new CountDownLatch(1); 18 | // main线程将会等待所有ConnectionRunner结束后才能继续执行 19 | private static CountDownLatch end; 20 | 21 | public static void main(String[] args) { 22 | // 线程数量,可以修改线程数量进行观察 23 | int threadCount = 50; 24 | end = new CountDownLatch(threadCount); 25 | int count = 20; 26 | AtomicInteger got = new AtomicInteger(); 27 | AtomicInteger notGot = new AtomicInteger(); 28 | for (int i = 0; i < threadCount; i++) { 29 | Thread thread = new Thread(new ConnectionRunner(count, got, notGot), "ConnectionRunnerThread"); 30 | thread.start(); 31 | } 32 | try { 33 | start.countDown(); 34 | // main主线程等待所有的线程完成工作 35 | end.await(); 36 | System.out.println("total invoke: " + (threadCount * count)); 37 | System.out.println("got connection: " + got); 38 | System.out.println("not got connection " + notGot); 39 | } catch (InterruptedException e) { 40 | e.printStackTrace(); 41 | } 42 | } 43 | 44 | private static class ConnectionRunner implements Runnable { 45 | // 尝试获取次数 46 | int count; 47 | // 获得的次数 48 | AtomicInteger got; 49 | // 未获得的次数 50 | AtomicInteger notGot; 51 | 52 | public ConnectionRunner(int count, AtomicInteger got, AtomicInteger notGot) { 53 | this.count = count; 54 | this.got = got; 55 | this.notGot = notGot; 56 | } 57 | 58 | @Override 59 | public void run() { 60 | try { 61 | start.await(); 62 | } catch (Exception e) { 63 | e.printStackTrace(); 64 | } 65 | while (count > 0) { 66 | try { 67 | // 从线程池中获取连接,如果1000ms内无法获取到,将会返回null 68 | // 分别统计连接获取的数量got和未获取到的数量notGot 69 | Connection connection = pool.fetchConnection(1000); 70 | if (connection != null) { 71 | try { 72 | connection.createStatement(); 73 | // 通过代理模拟获得了connection执行操作 74 | connection.commit(); 75 | } catch (SQLException e) { 76 | e.printStackTrace(); 77 | } finally { 78 | pool.releaseConnection(connection); 79 | got.incrementAndGet(); 80 | } 81 | } else { 82 | notGot.incrementAndGet(); 83 | } 84 | } catch (InterruptedException e) { 85 | e.printStackTrace(); 86 | } finally { 87 | count--; 88 | } 89 | } 90 | // 每个线程自己执行完操作之后将end减少 91 | end.countDown(); 92 | } 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /src/main/java/com/chao/concurrency_basic/chapter13_SIMPLE_THREAD_POOL/SimpleThreadPool.java: -------------------------------------------------------------------------------- 1 | package com.chao.concurrency_basic.chapter13_SIMPLE_THREAD_POOL; 2 | 3 | import java.util.ArrayList; 4 | import java.util.LinkedList; 5 | 6 | /** 7 | * 实现了简单的线程池的创建、任务队列、 8 | * 维护线程池中线程的状态、线程接受任务并执行 9 | */ 10 | public class SimpleThreadPool { 11 | // 线程池默认大小为10 12 | private static final int DEFAULT_SIZE = 10; 13 | private int size; 14 | 15 | // 任务队列 16 | private static final LinkedList TASK_QUEUE = new LinkedList<>(); 17 | private static final String PREFIX = "Simple-thread-"; 18 | // 线程队列 19 | private static final ArrayList THREAD_QUEUE = new ArrayList<>(); 20 | // 将线程池中的所有线程归于一个线程组 21 | private static final ThreadGroup THREAD_GROUP = new ThreadGroup("Simple-ThreadGroup"); 22 | private static volatile int seq = 0; 23 | 24 | public SimpleThreadPool(){ 25 | this(DEFAULT_SIZE); 26 | } 27 | 28 | public SimpleThreadPool(int size){ 29 | this.size = size; 30 | init(); 31 | } 32 | 33 | private void init(){ 34 | for(int i = 0; i implements ThreadPool { 18 | // 线程池最大数量 19 | private static final int MAX_WORKER_NUMBERS = 10; 20 | // 线程池默认数量 21 | private static final int DEFAULT_WORKER_NUMBERS = 5; 22 | // 线程池最小数量 23 | private static final int MIN_WORKER_NUMBERS = 1; 24 | // 任务等待列表 25 | private final LinkedList jobs = new LinkedList<>(); 26 | // 工作者列表 27 | private final List workers = Collections.synchronizedList(new ArrayList()); 28 | // 当前工作者数量 29 | private int workerNum = DEFAULT_WORKER_NUMBERS; 30 | // 编号生成 31 | private AtomicLong threadNum = new AtomicLong(); 32 | 33 | // 缺省情况下使用默认线程数量 34 | public DefaultThreadPool() { 35 | initializeWorkers(DEFAULT_WORKER_NUMBERS); 36 | } 37 | 38 | // 初始化工作者线程 39 | private void initializeWorkers(int num) { 40 | for (int i = 0; i < num; i++) { 41 | Worker worker = new Worker(); 42 | workers.add(worker); 43 | Thread thread = new Thread(worker, "ThreadPool-Worker-" + threadNum.getAndIncrement()); 44 | thread.start(); 45 | } 46 | } 47 | 48 | // 有參时通过比较看最后得出需要初始化的工作者线程数量 49 | public DefaultThreadPool(int num) { 50 | workerNum = num > MAX_WORKER_NUMBERS ? MAX_WORKER_NUMBERS : num; 51 | initializeWorkers(workerNum); 52 | } 53 | 54 | /** 55 | * 提交任务,只是将任务加入任务队列,之后唤醒队列中等待的线程 56 | * @param job 57 | */ 58 | @Override 59 | public void execute(Job job) { 60 | if (job != null) { 61 | synchronized (jobs) { 62 | jobs.addLast(job); 63 | jobs.notifyAll(); 64 | } 65 | } 66 | } 67 | 68 | @Override 69 | public void shutdown() { 70 | workers.forEach(Worker::shutdown); 71 | } 72 | 73 | /** 74 | * 添加新的工作者线程时,计算出需要添加的数目, 75 | * 再使用初始化工作者线程方法添加 76 | * 77 | * 添加之前需要进行工作者线程数量的验证 78 | * @param num 79 | */ 80 | @Override 81 | public void addWorker(int num) { 82 | synchronized (jobs) { 83 | if (num + this.workerNum > MAX_WORKER_NUMBERS) { 84 | // 超出最大数量之后,将需要添加的数量减少至不超过最大数量的数值 85 | num = MAX_WORKER_NUMBERS - this.workerNum; 86 | initializeWorkers(num); 87 | this.workerNum += num; 88 | } 89 | } 90 | } 91 | 92 | @Override 93 | public void removeWorker(int num) { 94 | synchronized (jobs) { 95 | // 防止需要删除的工作者线程大于(超出范围)或等于(默认最小线程无法达成)workNum 96 | if (num >= this.workerNum) { 97 | throw new IllegalArgumentException("beyond workNum"); 98 | } 99 | for (int i = 0; i < num; ) { 100 | Worker worker = workers.get(i); 101 | if (workers.remove(worker)) { 102 | worker.shutdown(); 103 | i++; 104 | } 105 | } 106 | this.workerNum -= num; 107 | } 108 | } 109 | 110 | public int getWorkerNum() { 111 | return workerNum; 112 | } 113 | 114 | class Worker implements Runnable { 115 | private volatile boolean running = true; 116 | 117 | @Override 118 | public void run() { 119 | while (running) { 120 | Job job = null; 121 | synchronized (jobs) { 122 | // 如果jobs(工作列表)是空的,那么线程等待 123 | while (jobs.isEmpty()) { 124 | try { 125 | jobs.wait(); 126 | } catch (InterruptedException e) { 127 | Thread.currentThread().interrupt(); 128 | return; 129 | } 130 | } 131 | // 取出一个job 132 | job = jobs.removeFirst(); 133 | } //这里重要的一点是:获取到任务之后应该释放锁,让其他线程有机会获取锁并获得任务 134 | if (job != null) { 135 | try { 136 | job.run(); 137 | } catch (Exception e) { 138 | // ignore 139 | } 140 | } 141 | } 142 | } 143 | 144 | public void shutdown() { 145 | running = false; 146 | } 147 | } 148 | 149 | } 150 | -------------------------------------------------------------------------------- /src/main/java/com/chao/concurrency_basic/chapter13_SIMPLE_THREAD_POOL/SimpleThreadPool2.java: -------------------------------------------------------------------------------- 1 | package com.chao.concurrency_basic.chapter13_SIMPLE_THREAD_POOL; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Iterator; 5 | import java.util.LinkedList; 6 | 7 | /** 8 | * 1.实现了简单的线程池的创建、任务队列、 9 | * 维护线程池中线程的状态、线程接受任务并执行 10 | * 11 | * 增加拒绝策略 12 | * 增加线程池关闭 13 | */ 14 | public class SimpleThreadPool2 { 15 | private int size; 16 | private int queueSize; 17 | private RejectPolicy rejectPolicy; 18 | private volatile boolean destroy; 19 | 20 | // 线程池默认大小为10 21 | private static final int DEFAULT_SIZE = 10; 22 | // 任务队列默认大小 23 | private static final int DEFAULT_QUEUE_SIZE = 1000; 24 | // 任务队列 25 | private static LinkedList TASK_QUEUE = new LinkedList<>(); 26 | private static final String PREFIX = "Simple-thread-"; 27 | // 线程队列 28 | private static final ArrayList THREAD_QUEUE = new ArrayList<>(); 29 | // 将线程池中的所有线程归于一个线程组 30 | private static final ThreadGroup THREAD_GROUP = new ThreadGroup("Simple-ThreadGroup"); 31 | // 线程名序列 32 | private static volatile int seq = 0; 33 | // 默认拒绝策略 34 | private static final RejectPolicy DEFAULT_REJECT_POLICY= ()->{throw new RejectPolicyException("Task Queue is full.");}; 35 | 36 | public SimpleThreadPool2() { 37 | this(DEFAULT_SIZE,DEFAULT_QUEUE_SIZE,DEFAULT_REJECT_POLICY); 38 | } 39 | 40 | public SimpleThreadPool2(int size,int queueSize,RejectPolicy rejectPolicy) { 41 | this.size = size; 42 | this.queueSize = queueSize; 43 | this.rejectPolicy = rejectPolicy; 44 | init(); 45 | } 46 | 47 | private void init() { 48 | for (int i = 0; i < size; i++) { 49 | createWorkThread(); 50 | } 51 | } 52 | 53 | // 创建一个线程 54 | private void createWorkThread() { 55 | WorkThread t = new WorkThread(THREAD_GROUP, PREFIX + (++seq)); 56 | t.start(); 57 | THREAD_QUEUE.add(t); 58 | } 59 | 60 | // 提交任务 61 | public void submit(Runnable runnable) { 62 | // 线程池被销毁不可再新增任务 63 | if(destroy) 64 | throw new RuntimeException("The Simple-Thread has destroyed and not allow to submit task."); 65 | // 超过当前任务队列的最大容量,执行拒绝策略 66 | if(TASK_QUEUE.size() > queueSize) 67 | rejectPolicy.reject(); 68 | 69 | synchronized (TASK_QUEUE) { 70 | TASK_QUEUE.addLast(runnable); 71 | // 任务加入后,通知处于等待中的线程 72 | TASK_QUEUE.notifyAll(); 73 | } 74 | } 75 | 76 | // 关闭线程池 77 | public void shutdown() throws InterruptedException { 78 | if(destroy) 79 | throw new RuntimeException("The Simple-Thread already destroyed."); 80 | // 等待任务队列中的所有任务完成 81 | while (!TASK_QUEUE.isEmpty()){ 82 | Thread.sleep(50); 83 | } 84 | // 逐个关闭线程 85 | synchronized (THREAD_QUEUE){ 86 | int threadCount = THREAD_QUEUE.size(); 87 | // 不断轮询所有线程,关闭线程 88 | while(threadCount > 0){ 89 | for (Iterator it = THREAD_QUEUE.iterator();it.hasNext();){ 90 | WorkThread t = it.next(); 91 | if(t.getTaskState() == TaskState.BLOCKED){ 92 | t.close(); 93 | t.interrupt(); 94 | threadCount--; 95 | it.remove(); 96 | }else { 97 | Thread.sleep(100); 98 | } 99 | } 100 | } 101 | destroy = true; 102 | System.out.println("The Simple-Thread is shutdown"); 103 | System.out.println(THREAD_QUEUE.size()); 104 | } 105 | } 106 | 107 | public int getSize() { 108 | return size; 109 | } 110 | 111 | public int getQueueSize() { 112 | return queueSize; 113 | } 114 | 115 | public RejectPolicy getRejectPolicy() { 116 | return rejectPolicy; 117 | } 118 | 119 | private enum TaskState { 120 | FREE, RUNNING, BLOCKED, DEAD 121 | } 122 | 123 | private class WorkThread extends Thread { 124 | private TaskState taskState = TaskState.FREE; 125 | 126 | WorkThread(ThreadGroup g, String name) { 127 | super(g, name); 128 | } 129 | 130 | /** 131 | * 线程状态为非DEAD状态时,检测任务队列中是否有任务,有则开始接任务 132 | * 当其他线程正在取任务时,其他线程等待(状态为阻塞状态) 133 | * 从任务队列中取走任务(状态变为运行中),然后开始做任务 134 | * 做完任务后(状态变为自由状态,等待下一个任务) 135 | * 线程不结束,回到线程池中 136 | */ 137 | public void run() { 138 | OUTER: 139 | while (this.taskState != TaskState.DEAD) { 140 | Runnable runnable = null; 141 | synchronized (TASK_QUEUE) { 142 | while (TASK_QUEUE.isEmpty()) { 143 | try { 144 | this.taskState = TaskState.BLOCKED; 145 | TASK_QUEUE.wait(); 146 | } catch (InterruptedException e) { 147 | // 当线程任务时被打断,回到线程池重新接任务 148 | this.taskState = TaskState.FREE; 149 | break OUTER; 150 | } 151 | // 被唤醒之后检测到任务队列非空则退出循环接任务 152 | } 153 | // 拿到任务 154 | runnable = TASK_QUEUE.removeFirst(); 155 | } 156 | // 执行任务,放在synchronized外, 157 | // 让线程执行任务的同时释放锁,让其他线程可以接任务 158 | if (runnable != null) { 159 | this.taskState = TaskState.RUNNING; 160 | runnable.run(); 161 | this.taskState = TaskState.FREE; 162 | } 163 | } 164 | } 165 | 166 | private void close() { 167 | this.taskState = TaskState.DEAD; 168 | } 169 | 170 | private TaskState getTaskState() { 171 | return taskState; 172 | } 173 | } 174 | 175 | private static class RejectPolicyException extends RuntimeException{ 176 | RejectPolicyException(String msg){ 177 | super(msg); 178 | } 179 | } 180 | 181 | private interface RejectPolicy{ 182 | void reject() throws RejectPolicyException; 183 | } 184 | 185 | 186 | } 187 | -------------------------------------------------------------------------------- /src/main/java/com/chao/concurrency_basic/chapter13_SIMPLE_THREAD_POOL/SimpleThreadPool3.java: -------------------------------------------------------------------------------- 1 | package com.chao.concurrency_basic.chapter13_SIMPLE_THREAD_POOL; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Iterator; 5 | import java.util.LinkedList; 6 | 7 | /** 8 | * 1.实现了简单的线程池的创建、任务队列、 9 | * 维护线程池中线程的状态、线程接受任务并执行 10 | * 2.实现了简单的拒绝策略,线程池关闭 11 | * 12 | * 增加自动扩充线程数量 13 | * 增加闲时自动回收 14 | */ 15 | public class SimpleThreadPool3 extends Thread { 16 | // 当前线程池线程数量 17 | private volatile int size; 18 | // 当前任务队列数量 19 | private int queueSize; 20 | // 当前拒绝策略 21 | private RejectPolicy rejectPolicy; 22 | // 线程池是否存活标识 23 | private volatile boolean destroy = false; 24 | // 三个线程个数大小关系:min < active < max 25 | // 最小保持的工作线程 26 | private int minThread; 27 | // 活动的工作线程 28 | private int activeThread; 29 | // 最大可用工作线程 30 | private int maxThread; 31 | 32 | // 默认最小保持的工作线程 33 | private static final int DEFAULT_MIN_THREAD = 4; 34 | // 默认活动的工作线程 35 | private static final int DEFAULT_ACTIVE_THREAD = 8; 36 | // 默认最大可用工作线程 37 | private static final int DEFAULT_MAX_THREAD = 16; 38 | // 任务队列默认大小 39 | private static final int DEFAULT_QUEUE_SIZE = 1000; 40 | // 任务队列 41 | private static final LinkedList TASK_QUEUE = new LinkedList<>(); 42 | private static final String PREFIX = "Simple-thread-"; 43 | // 线程队列 44 | private static final ArrayList THREAD_QUEUE = new ArrayList<>(); 45 | // 将线程池中的所有线程归于一个线程组 46 | private static final ThreadGroup THREAD_GROUP = new ThreadGroup("Simple-ThreadGroup"); 47 | // 线程名序列 48 | private static volatile int seq = 0; 49 | // 默认拒绝策略 50 | private static final RejectPolicy DEFAULT_REJECT_POLICY = () -> { 51 | throw new RejectPolicyException("Task Queue is full."); 52 | }; 53 | 54 | public SimpleThreadPool3() { 55 | this(DEFAULT_MIN_THREAD, DEFAULT_ACTIVE_THREAD, DEFAULT_MAX_THREAD, DEFAULT_QUEUE_SIZE, DEFAULT_REJECT_POLICY); 56 | } 57 | 58 | public SimpleThreadPool3(int minThread, int activeThread, int maxThread, int queueSize, RejectPolicy rejectPolicy) { 59 | this.size = minThread; 60 | this.minThread = minThread; 61 | this.activeThread = activeThread; 62 | this.maxThread = maxThread; 63 | this.queueSize = queueSize; 64 | this.rejectPolicy = rejectPolicy; 65 | init(); 66 | } 67 | 68 | private void init() { 69 | for (int i = 0; i < size; i++) { 70 | createWorkThread(); 71 | } 72 | this.start(); 73 | } 74 | 75 | // 创建一个线程 76 | private void createWorkThread() { 77 | WorkThread t = new WorkThread(THREAD_GROUP, PREFIX + (++seq)); 78 | t.start(); 79 | THREAD_QUEUE.add(t); 80 | } 81 | 82 | // 维护线程池中的线程数量 83 | @Override 84 | public void run() { 85 | while (!destroy) { 86 | /** 87 | * 1.当最小线程数min不足以应付任务时,扩充线程至active个 88 | * 2.当活动线程数active不足以应付任务时,扩充线程至max个 89 | * 3.当任务队列为空,将那些空闲的线程杀死,减小至min个 90 | * 任务队列为空或执行任务的线程少于最小线程数量,总是维护最小线程数量的线程 91 | */ 92 | if ((size < TASK_QUEUE.size() / 4) && (size < activeThread)) { 93 | synchronized (THREAD_QUEUE) { 94 | for (int i = size; i < activeThread; i++) { 95 | createWorkThread(); 96 | size++; 97 | } 98 | } 99 | } else if ((size < TASK_QUEUE.size() / 2) && (size < maxThread)) { 100 | synchronized (THREAD_QUEUE) { 101 | for (int i = size; i < maxThread; i++) { 102 | createWorkThread(); 103 | size++; 104 | } 105 | } 106 | } else if (TASK_QUEUE.isEmpty() && (size > minThread)) { 107 | synchronized (THREAD_QUEUE) { 108 | int threadCount = THREAD_QUEUE.size(); 109 | closeThread(threadCount, minThread); 110 | } 111 | } 112 | 113 | try { 114 | Thread.sleep(1_000); 115 | } catch (InterruptedException e) { 116 | e.printStackTrace(); 117 | } 118 | System.out.printf("min:%d, active:%d, max:%d, current:%d, size:%d,task_queue:%d", minThread, activeThread, 119 | maxThread, THREAD_GROUP.activeCount(), size, TASK_QUEUE.size()); 120 | System.out.println(); 121 | 122 | } 123 | } 124 | 125 | /** 126 | * 提交任务 127 | * @param runnable 任务 128 | */ 129 | public void submit(Runnable runnable) { 130 | // 线程池被销毁不可再新增任务 131 | if (destroy) 132 | throw new RuntimeException("The Simple-Thread has destroyed and not allow to submit task."); 133 | // 超过当前任务队列的最大容量,执行拒绝策略 134 | if (TASK_QUEUE.size() > queueSize) 135 | rejectPolicy.reject(); 136 | 137 | synchronized (TASK_QUEUE) { 138 | TASK_QUEUE.addLast(runnable); 139 | // 任务加入后,通知处于等待中的线程 140 | TASK_QUEUE.notifyAll(); 141 | } 142 | } 143 | 144 | // 关闭线程池 145 | public void shutdown() throws InterruptedException { 146 | if (destroy) 147 | throw new RuntimeException("The Simple-Thread already destroyed."); 148 | // 等待任务队列中的所有任务完成 149 | while (!TASK_QUEUE.isEmpty()) { 150 | Thread.sleep(50); 151 | } 152 | // 逐个关闭线程 153 | synchronized (THREAD_QUEUE) { 154 | int threadCount = THREAD_QUEUE.size(); 155 | // 不断轮询所有线程,关闭线程 156 | closeThread(threadCount, 0); 157 | destroy = true; 158 | System.out.println("The Simple-Thread is shutdown"); 159 | } 160 | } 161 | 162 | /** 163 | * 关闭线程池中的线程 164 | * @param threadCount 线程池中现有线程 165 | * @param remainingThread 关闭线程后应该剩下的线程 166 | */ 167 | private void closeThread(int threadCount, int remainingThread) { 168 | if(threadCount < remainingThread) 169 | return; 170 | 171 | while (threadCount > remainingThread) { 172 | for (Iterator it = THREAD_QUEUE.iterator(); it.hasNext(); ) { 173 | WorkThread t = it.next(); 174 | if ((threadCount > remainingThread) && (t.getTaskState() == TaskState.BLOCKED)) { 175 | t.close(); 176 | t.interrupt(); 177 | threadCount--; 178 | it.remove(); 179 | size--; 180 | } else { 181 | try { 182 | Thread.sleep(100); 183 | } catch (InterruptedException e) { 184 | e.printStackTrace(); 185 | } 186 | } 187 | } 188 | } 189 | } 190 | 191 | public int getSize() { 192 | return size; 193 | } 194 | 195 | public int getQueueSize() { 196 | return queueSize; 197 | } 198 | 199 | public RejectPolicy getRejectPolicy() { 200 | return rejectPolicy; 201 | } 202 | 203 | public boolean isDestroy() { 204 | return destroy; 205 | } 206 | 207 | public int getMinThread() { 208 | return minThread; 209 | } 210 | 211 | public int getActiveThread() { 212 | return activeThread; 213 | } 214 | 215 | public int getMaxThread() { 216 | return maxThread; 217 | } 218 | 219 | private enum TaskState { 220 | FREE, RUNNING, BLOCKED, DEAD 221 | } 222 | 223 | private class WorkThread extends Thread { 224 | private TaskState taskState = TaskState.FREE; 225 | 226 | WorkThread(ThreadGroup g, String name) { 227 | super(g, name); 228 | } 229 | 230 | /** 231 | * 线程状态为非DEAD状态时,检测任务队列中是否有任务,有则开始接任务 232 | * 当其他线程正在取任务时,其他线程等待(状态为阻塞状态) 233 | * 从任务队列中取走任务(状态变为运行中),然后开始做任务 234 | * 做完任务后(状态变为自由状态,等待下一个任务) 235 | * 线程不结束,回到线程池中 236 | */ 237 | public void run() { 238 | OUTER: 239 | while (this.taskState != TaskState.DEAD) { 240 | Runnable runnable = null; 241 | synchronized (TASK_QUEUE) { 242 | while (TASK_QUEUE.isEmpty()) { 243 | try { 244 | this.taskState = TaskState.BLOCKED; 245 | TASK_QUEUE.wait(); 246 | } catch (InterruptedException e) { 247 | // 当线程任务时被打断,回到线程池重新接任务 248 | break OUTER; 249 | } 250 | // 被唤醒之后检测到任务队列非空则退出循环接任务 251 | } 252 | // 拿到任务 253 | runnable = TASK_QUEUE.removeFirst(); 254 | } 255 | // 执行任务,放在synchronized外, 256 | // 让线程执行任务的同时释放锁,让其他线程可以接任务 257 | if (runnable != null) { 258 | this.taskState = TaskState.RUNNING; 259 | runnable.run(); 260 | this.taskState = TaskState.FREE; 261 | } 262 | } 263 | } 264 | 265 | private void close() { 266 | this.taskState = TaskState.DEAD; 267 | } 268 | 269 | private TaskState getTaskState() { 270 | return taskState; 271 | } 272 | } 273 | 274 | private static class RejectPolicyException extends RuntimeException { 275 | RejectPolicyException(String msg) { 276 | super(msg); 277 | } 278 | } 279 | 280 | private interface RejectPolicy { 281 | void reject() throws RejectPolicyException; 282 | } 283 | 284 | 285 | } 286 | -------------------------------------------------------------------------------- /.idea/inspectionProfiles/Project_Default.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 95 | -------------------------------------------------------------------------------- /.idea/uiDesigner.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | --------------------------------------------------------------------------------