多线程回顾
线程状态
public enum State {
//新生
NEW,
//运行
RUNNABLE,
//阻塞
BLOCKED,
// 等待
WAITING,
// 超时等待
TIMED_WAITING,
// 终止
TERMINATED;
}
wait和sleep的区别
-
来自不同的类
wait 来自Object
sleep 来自Thread -
关于锁的释放
wait会释放锁,sleep不会释放锁 -
使用的范围不同
wait 必须在同步代码块中
sleep 可以在任何地方睡 -
需要捕获异常
wait 不需要捕获异常
sleep 必须要捕获异常
传统的synchronized锁
public class ThreadTest {
public static void main(String[] args) {
SaleTicket saleTicket = new SaleTicket();
new Thread(()->{for(int i=0; i < 40; i++) {saleTicket.sale();}},"线程1").start();
new Thread(()->{for(int i=0; i < 40; i++) {saleTicket.sale();}},"线程2").start();
new Thread(()->{for(int i=0; i < 40; i++) {saleTicket.sale();}},"线程3").start();
}
static class SaleTicket {
private int num = 30;
public synchronized void sale() {
if (num > 0) {
System.out.println("线程:"+Thread.currentThread().getName()+" 售出了:"+(num--)+"张票 还剩"+num+"张");
}
}
}
}
Lock锁
Lock锁使用
private Lock mLock = new ReentrantLock(); // 1. 创建lock对象
mLock.lock(); //2. 执行业务代码前,先lock
try {
//业务代码
if (num > 0) {
System.out.println("线程:"+Thread.currentThread().getName()+" 售出了:"+(num--)+"张票 还剩"+num+"张");
}
} catch (Exception e) {
e.printStackTrace();
} finally {
mLock.unlock(); // 3.执行完业务代码后,unlock
}
static class SaleTicket {
private int num = 30;
private Lock mLock = new ReentrantLock();
public void sale() {
mLock.lock();
try {
if (num > 0) {
System.out.println("线程:"+Thread.currentThread().getName()+" 售出了:"+(num--)+"张票 还剩"+num+"张");
}
} catch (Exception e) {
e.printStackTrace();
} finally {
mLock.unlock();
}
}
}
synchronized和lock的区别
- synchronized是java内置的关键字,Lock是java类
- synchronized无法判断获取锁的状态,Lock可以判断是否获取到了锁
- synchronized会自动释放,Lock必须要手动解锁
网友评论