JUC(java.util.concurrent)
2024-05-22 16:46:32 65 举报
AI智能生成
java.util.current 并发包
作者其他创作
大纲/内容
线程与进程, 并行与并发
线程与进程: 线程是操作系统执行运算的最小单位,一个进程包含多个线程
并发: 同一时刻,多个线程竞争同一资源
并发: 多个线程并行执行
不安全集合
<b><font color="#f1753f">【方式一】</font></b>直接使用安全集合(Vector、Hashtable)
<b><font color="#f1753f">【方式二】</font></b>使用 Collections 工具类转换
<b><font color="#c41230">【方式三】</font></b>使用JUC 下的安全集合(CopyOnWriteArrayList、CopyOnWriteArraySet、ConcurrentHashMap)
Synchronized 的8锁
<b><font color="#0076b3">锁对象 & 锁模板类Class</font></b>
Synchronized 和 Lock 区别
Synchronized 内置的 Java 关键字, Lock 是一个 Java 接口
Synchronized 无法判断锁的状态, Lock 可以判断锁的状态
Synchronized 会自动释放锁, Lock 必须要手动释放锁! 如果不释放锁,就会出现死锁
Synchronized 线程1(获得锁 阻塞) 线程2(一直等待),Lock 锁就不一定会一直等下去
Synchronized 可重入锁,不可中断的,非公平; Lock 可重入锁,可以判断锁,非公平(默认是非公平,但可以自己设置)
Synchronized 适合少量的代码同步,Lock 适合锁大量的同步代码
线程之间的通信
高内聚低耦合前提下,线程操作资源类
判断——> 干活——> 通知
不能使用 if 判断 (虚假唤醒),<b><font color="#c41230">要使用 while</font></b>
<b><font color="#f1753f">【实现方式一】</font></b>Synchronized + wait + notify
<b><font color="#f1753f">【实现方式二】</font></b>Lock + Condition + awrite + signal
注意但,<font color="#c41230">在调用 <b>signal </b>方法时要先改变标志位</font>
Callable 接口
与 Runnable 接口对比, 有返回值,call 方法抛出异常
FutureTask 未来任务,只会执行一次
常用辅助类
CountDownLatch(下课关门)
指定先运行的线程数量,当这些线程运行完成,才会继续向下执行
线程中执行业务完成时,要调用 <b><font color="#924517">countDownLatch.countDown()</font></b>
在指定数量的线程下面调用,<b><font color="#924517">countDownLatch.await()</font></b>, 保证指定数量的线程先执行完成,才会继续向下执行
CyclicBarrier (召唤龙珠)
当线程执行业务代码完成时,调用 cyclicBarrier.await(),当计数器达到指定的数时,执行CyclicBarrier 对象中的 lambda 表达式
Semaphore (争车位)
用于控制多线程的并发数和多个共享资源的互斥使用
acquire() 占用
release() 释放
ReadWriteLock 读写锁
BlockingQueue 阻塞队列
阻塞队列七大实现
<font color="#c41230"><b>ArrayBlockingQueue : 由数组结构组成的有界阻塞队列</b></font>
<b><font color="#c41230">LinkedBlockingQueue : 由链表结构组成的有界(但大小默认值为Integer.MAX_VALUE) 阻塞队列</font></b>
PriorityBlockingQueue : 支持优先级排序的无界阻塞队列
DelayQueue : 使用优先级队列实现的延迟无界阻塞队列
<b><font color="#c41230">SynchronousQueue : 不存储元素的阻塞队列,也既单个元素的队列</font></b>
LinkedTransferQueue : 有链表组成的无界阻塞队列
LinkedBlocking<b><font color="#f384ae">Deque</font></b> : 由链表组成的双向阻塞队列
BlockingQueue 的核心方法
案例代码
ThreadPoolExecutor 线程池
使用 Executors 工具类
Executors.newFixedThreadPool(int)
指定固定线程数
Executors.newSingleThreadExecutor()
单个
Executors.newCacheThreadPool()
可扩容
线程池几个重要参数
1、corePoolSize :线程池中的<b><font color="#0076b3">常驻核心线程数</font></b>
2、maximumPoolSize : 线程池中能够容纳同时执行的<b><font color="#0076b3">数最大线程</font></b>(此值必须大于等于1)
cup 密集型 : cup 核数 +1
Runtime.getRuntime().availableProcessors() 获取CUP 核数
Io 密集型:判断程序中十分好资源的 IO 线程数, 只要设置比这个数大就行
3、keepAliveTime : 多余的空闲线程的存活时间,<br>当前线程池中线程数量超过corePoolSize 时,当空闲时间<br>达到 keepAliveTime 时,多余线程会被销毁直到只剩下<br>corePoolSize 个线程为止。
4、unit : keepAliveTime 的单位
5、workQueue : 任务队列,存放被提交但尚未被执行的任务
6、threadFactory : 便是生成线程池中工作线程的线程工厂,用于创建线程,<b><font color="#0076b3">一般默认即可</font></b>
7、handler : 拒绝策略, 表示当队列满了,并且工作线程大于等于线程<br>池的最大线程数(maximumPoolSize)时,如何来拒绝请求执行的策略
AbortPolicy(默认) :中断策略,直接抛出 RejectedExecutionException 异常
CallerRunsPolicy : 调用者运行, 该策略不会抛出异常,而是将拒绝的任务退回给调用者
DiscardPolicy : 抛弃无法处理的任务,不会抛出异常,
DiscardOldesPolicy : 抛弃队列中等待最久的任务,然后把当前任务加入到队列中,尝试再次提交当前任务
0 条评论
下一页