什么是JUC
其实就是java.util.concurrent
包的简称,最开始出现在JDK1.5中.
线程和进程
进程
一个运行中的程序集合,一个进程往往包含多个线程,至少包含1个线程,
Java中默认有2个线程,一个Mian线程,一个GC线程
线程
线程是操作系统弄够运算调度的最小单位,
对Java而言创建thread: 继承自thread,实现runnable接口,实现callable接口
Java真的可以开启线程吗? 开不了的,底层是用native关键词修饰.调用本地实现
并发和并行
并发(多线程操作同一个资源,交替执行)
- CPU一核, 模拟出来多条线程,天下武功,唯快不破,快速交替
并行(多个人一起行走, 同时进行)
- CPU多核,多个线程同时进行 ; 使用线程池操作
并发编程的本质:充分利用CPU的资源
Wait/Sleep的区别
来自不同的类
wait来自object类, sleep来自线程类
关于锁的释放
wait会释放锁, sleep不会释放锁
使用的范围不同
wait必须在同步代码块中
sleep可以在任何地方睡
是否需要捕获异常
wait不需要捕获异常
sleep需要捕获异常
Lock锁
Lock是一个接口,其基本功能和Synchronized
大差不差,两者对比如下:
Synchronized | Lock |
---|---|
Java内置关键字 | Java的一个接口 |
无法判断获取锁的状态 | 可以判断是否获取到锁 |
自动释放锁 | 必须手动释放 |
线程 1(获得锁,阻塞)、线程2(等待,傻傻的等) | Lock锁就不一定会等待下去 |
可重入锁,不可以中断,非公平 | 可重入锁,可以判断锁,非公平(可设置) |
适合少量代码 | 适合大量代码 |
Lock有三个实现类:
- ReentrantLock 可重入锁(常用)
- ReadLock 读锁
- WriteLock 写锁
公平锁/非公平锁
公平锁: 十分公平: 可以先来后到,一定要排队
非公平锁: 十分不公平,可以插队(默认)
public static void main(String[] args) {
Ticket ticket = new Ticket();
new Thread(() -> {
for (int i = 0; i < 40; i++) ticket.sale();
}, "a").start();
new Thread(() -> {
for (int i = 0; i < 40; i++) ticket.sale();
}, "b").start();
new Thread(() -> {
for (int i = 0; i < 40; i++) ticket.sale();
}, "c").start();
}
static class Ticket {
private int ticketNum = 30;
private Lock lock = new ReentrantLock(true);
public void sale() {
lock.lock();
try {
if (this.ticketNum > 0) {
System.out.println(Thread.currentThread().getName() + "购得第" + ticketNum-- + "张票, 剩余" + ticketNum + "张票");
}
//增加错误的发生几率
Thread.sleep(10);
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}
参考
文章1: https://blog.csdn.net/qq_22155255/article/details/109749311