Lock 锁(*)
传统 synchronized
package pers.vincent.matrix.subject.juc;
public class JucTest1 {
public static void main(String[] args) {
// 获取CPU核数
// System.out.println(Runtime.getRuntime().availableProcessors());
// 多个线程操作同一个资源类
Ticket ticket = new Ticket();
// 函数式接口 jdk 1.8 lambda 表达式 (参数)->{ 代码块 }
new Thread(()->{
for (int i = 0; i < 60; i++) {
ticket.sale();
}
}, "A").start();
new Thread(()->{
for (int i = 0; i < 60; i++) {
ticket.sale();
}
}, "B").start();
new Thread(()->{
for (int i = 0; i < 60; i++) {
ticket.sale();
}
}, "C").start();
}
}
class Ticket{
private int ticketNum = 50;
// synchronized 的本质:锁和排队
public synchronized void sale(){
if(ticketNum>0){
System.out.println(Thread.currentThread().getName() + "卖出了第" + ticketNum-- + "票, 剩余票数=" + ticketNum);
}
}
}
Lock 接口
Lock l = ...; l.lock(); try { // access the resource protected by this lock } finally { l.unlock(); }
1.Lock 的实现类
- ReentrantLock : 可重复锁
- ReentrantReadWriteLock.ReadLock
- ReentrantReadWriteLock.WriteLock
ReentrantLock
公平锁:十分公平,先来后到
非公平锁:十分不公平,可以插队(默认)
2.Lock 代码实现
package pers.vincent.matrix.subject.juc;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class JUCTest2 {
public static void main(String[] args) {
Ticket2 ticket = new Ticket2();
new Thread(()->{ for (int i = 0; i < 60; i++) ticket.sale(); }, "A").start();
new Thread(()->{ for (int i = 0; i < 60; i++) ticket.sale(); }, "B").start();
new Thread(()->{ for (int i = 0; i < 60; i++) ticket.sale(); }, "C").start();
}
}
// Lock
// 1. new ReentrantLock()
// 2. lock.Lock()
// 3. finally lock.unlock();
class Ticket2{
private int ticketNum = 50;
Lock lock = new ReentrantLock();
public void sale(){
lock.lock();
lock.tryLock();// 尝试获取锁
try {
if(ticketNum>0){
System.out.println(Thread.currentThread().getName() + "卖出了第" + ticketNum-- + "票, 剩余票数=" + ticketNum);
}
}catch (Exception e){
e.printStackTrace();
}finally {
lock.unlock();
}
}
}
synchronized 和 Lock 的区别
- Synchronized 内置的 Java 关键字,Lock 是一个Java类
- Synchronized 无法判断获取锁的状态,Lock 可以判断是否获取到了锁
- Synchronized 会自动释放锁,Lock 必须手动释放锁,如果不释放,死锁
- Synchronized 如果线程1(获得锁,阻塞)、线程2(等待);Lock锁就不一定会等待下去
- Synchronized 可重入锁,不可以中断,非公平;Lock 可重入锁,可以判断锁,非公平(可以自己设置)
- Synchronized 适合少量的代码同步问题;Lock 适合锁大量的同步代码