- 什么是JUC
- 进程和线程回顾
- Lock锁
- 生产者和消费者
- 8锁的线程
- 集合类不安全
- Callable
- CountDownLatch、CyclicBarrier、Semaphore
- 读写锁
- 阻塞队列
- 线程池
- 四大函数式接口
- Stream流式计算
- 分支合并
- 异步回调
- JMM
- volatile
- 深入单例模式
- 深入理解CAS
- 原子引用
- 可重入锁、公平锁非公平锁、自旋锁、死锁...
一. 什么是JUC
java.util.concurrent 包是在并发编程中使用的工具类,有以下三个包:
- java.util.concurrent
- java.util.concurrent.atomic
- java.util.concurrent.locks
二. 进程和线程回顾
- 进程:进程是一个具有一定独立功能的程序关于某个数据集合的一次运行活动。它是操作系统动态执行的基本单元,在传统的操作系统中,进程既是基本的分配单元,也是基本的执行单元。
- 线程:通常在一个进程中可以包含若干个线程,当然一个进程中至少有一个线程,不然没有存在的意义,线程可以利用进程所有拥有的资源。在引入线程的操作系统中,通常都是把进程作为分配资源的基本单位,而把线程作为独立运行和独立调度的基本单位,由于线程比进程小,基本上不拥有系统资源,故对它的调度所付出的开销就会小得多,能更高效的提高系统多个程序间并发执行的程度。
白话:
- 进程:就是操作系统中运行的一个程序,QQ.exe, music.exe, word.exe ,这就是多个进程
- 线程:每个进程中都存在一个或者多个线程,比如用word写文章时,就会有一个线程默默帮你定时自动保存。
Java默认有几个线程?
- 2个:main线程、GC线程(垃圾回收线程)
线程对于Java而言:Thread、Runnable、Callable
Java真的可以开启线程吗?
- 开不了,start()方法底层调用的start0()是native本地方法,底层的C++
package com.gch.juc;
public class StartDemo1 {
public static void main(String[] args) {
new Thread().start(); // 实际上调用的是start0方法
}
}
并发、并行
- 并发编程:并发、并行
- 并发(多线程操作同一个资源) CPU一核,模拟出来多条线程,快速交替执行。
- 一个CPU一次只能执行一条指令
- 并行(多线程操作多个资源) CPU多核,多个线程可以同时执行;线程池
package com.gch.juc;
public class cpuCores {
public static void main(String[] args) {
// 获取CPU的核数
// CPU密集型、IO密集型
System.out.println(Runtime.getRuntime().availableProcessors()); // 12
}
}
- 并发编程的本质:充分利用CPU的资源,充分的利用处理器的每一个核,以达到最高的处理性能。
线程有几个状态?
wait/sleep区别:
- 来自不同的类:wait===>Object sleep===>Thread
企业当中,让线程休眠会用Thread.sleep吗?
- 不会,会用TimeUnit这个工具类来操作:
2. 关于锁的释放:有没有释放锁(释放资源)
- wait会释放锁
- sleep睡觉了,抱着锁睡觉,不会释放锁
- 最主要是sleep方法没有释放锁,而wait方法释放了锁,使得其他线程可以使用同步控制块或者方法。
- sleep是线程被调用时,占着cpu去睡觉,其他线程不能占用cpu,os认为该线程正在工作,不会让出系统资源
- wait是进入等待池等待,让出系统资源,其他线程可以占用cpu。
- sleep(100L)是占用cpu,线程休眠100毫秒,其他进程不能再占用cpu资源
- wait(100L)是进入等待池中等待,交出cpu等系统资源供其他进程使用,在这100毫秒中,该线程可以被其他线程notify,但不同的是其他在等待池中的线程不被notify不会出来,但这个线程在等待100毫秒后会自动进入就绪队列等待系统分配资源,换句话说,sleep(100)在100毫秒后肯定会运行,但wait在100毫秒后还有等待os调用分配资源,所以wait100的停止运行时间是不确定的,但至少是100毫秒。
- 就是说sleep有时间限制的就像闹钟一样到时候就叫了,而wait()是无限期的除非用户主动notify。
3、使用范围不同
- wait,notify和notifyAll只能在同步控制方法或者同步控制块里面使用
- 而sleep可以在任何地方使用。
synchronized(x){
//或者wait()
x.notify()
}
4. 是否需要捕获异常
- sleep必须捕获异常 --- throws InterruptedException
- 而wait,notify和notifyAll不需要捕获异常。
三. Lock锁(重点)