# JucDemo **Repository Path**: albertchen521/juc-demo ## Basic Information - **Project Name**: JucDemo - **Description**: 学习JUC过程中使用的小Demo - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 1 - **Forks**: 0 - **Created**: 2021-08-08 - **Last Updated**: 2022-04-01 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README 公平锁和非公平锁 公平锁:FIFO 非公平锁:可以抢占 ReentrantLock(false)是非公平锁 可重入锁(又名递归锁) 独占锁:值该锁一次只能被一个线程锁持有,对ReentrantLock和Synchronization而而言都是独占锁 共享锁:该锁可以被多个线程持有 对ReentrantReadWriteLock 对读是共享锁,对写是独占锁 CountDownlatch/CyclicBarrier/Semaphore 堵塞队列 BlockingQueue 实现类: ArrayBlockingQueue:由数组结构组成的有界阻塞队列 LinkBlockingQueue:由链表结构组成的有界(单大小默认) PriorityBlockingQueue: DelayQueue: SynchronousQueue:不存储元素的阻塞队列,也即单个元素的队列 用在哪里: 生产者消费者模式 线程池 消息占中间件 主要方法: Synchronized 和Lock区别 1.原始构成: Synchronized是关键字属于JVM层面 monitorenter(底层是通过monitor对象完成,其实wait/notify等方法也是依赖monitor对象 只用同步块或方法中才能调用wait/notify等方法 Lock是具体的类(java.util.concurrent.locks.Lock)是api层的锁 2.使用方法: Synchronized 不需要用户手动释放锁,当synchronized代码执行完后系统会自动让线程释放对锁的占用 ReentrantLock则需要用户手动释放锁,若没有释放锁会导致死锁 3.等待释放可中断 Synchronized不可以中断 ReentrantLock可以中断 4.加锁是否公平 Synchronized默认非公平锁 ReentrantLock默认非公平锁,当ReentrantLock(true)为公平锁 5.锁绑定多个条件condition Synchronized没有 Reetrantlock用来实现分组唤醒需要唤醒的线程们,可以精准唤醒,而不是像Synchronized那样随机唤醒一个或是唤醒全部 线程池做的工作主要是控制运行线程的数量,处理过程中将任务放入队列, 然后在线程创建后启动这些任务 ,如果线程数量超过了最大数量超出数量的线程排队等候,等其他线程执行完毕,再从队列中取出任务来执行 主要特点:线程复用;控制最大并发数;管理线程 1. 降低资源消耗。通过重复利用已创建的线程降低线程创建和销毁造成的消耗 2.提高响应速度。当任务结束时,任务可以不需要等到线程创建就能立即执行 3.提高线程的可管理性。线程时稀缺资源,如果无限制的创建,不仅会消耗系统资源,还会降低系统稳定性,使用线程池可以进行统一的分配,调优和监控 Java中的线程池时通过Executor框架实现的,该框架中使用了Executor,Executors,ExecutorService,ThreadPoolExecutor这几个类 Excutors.newFixedThreadPool(int) Excutors.newSingleThreadExcutor() Excutors.newCachedThreadPool() newFixedThreadPool主要特点: 1. 创建一个定长线程池,可以控制线程的最大并发数,超出的线程会在对列中等待 2. newFixedThreadPool创建的线程池的corePoolSize和maximumPoolSize值是相等的,它使用的是LinkedBlockingQueue对列 newSingleThreadExcutor主要特点: 1. 创建一个单线程化的线程池,它只有一个工作线程来执行任务,保证所有任务按照指定顺序来执行 1. 创建一个可缓存的线程池,如果线程池长度超过处理需要,可以灵活回收空虚线程 若无可回收,则新建线程。 2.newCachedThreadPool的corePoolSize为0、maximumPoolSize为Integer.MAX_VALUE使用队列为SynchronousQueue,也就是说来了任务就创建线程运行,当线程超过60s则销毁线程 tomcat 线程池分析 TaskQueen 复写对列offer(Runnable o)方法 1. 判断是否拿到父执行器 2. 判断当前线程池线程数量是否达到配置的最大线程数 submittedCount = 运行还没有结束线程 + 队列中线程 判断成功则调用父类offer将任务加入队列 3. 判断队列中的线程加正在工作线程是否小于当前线程池线程数量 判断成功则调用父类offer将任务加入队列 4. 存活线程数量小于最大核心数据