Lock锁(重点)
传统的synchronized
public class SaleTicketDemo01 {
//买票demo
public static void main(String[] args) {
Ticket ticket = new Ticket();
new Thread(()->{
for (int i = 0; i < 50; i++) {
ticket.sale();
}
},"A线程").start();
new Thread(()->{
for (int i = 0; i < 50; i++) {
ticket.sale();
}
},"B线程").start();
new Thread(()->{
for (int i = 0; i < 50; i++) {
ticket.sale();
}
},"C线程").start();
}
}
class Ticket{
private Integer number = 50;
//传统的线程锁
public synchronized void sale(){
if(number>0){
System.out.println(Thread.currentThread().getName()+"卖出了第"+number--+"张票"+"___剩余"+number);
}
}
}
Lock接口
- 上锁方法:lock
- 释放锁方法:unlock
lock中锁的分类:
- RenntrantLock.lock可重入锁
- RenntrantReadWriteLock.ReadLock读锁
- RenntrantReadWriteLock.WriteLock写锁
Lock接口内部:
- 公平锁:先来后到
- 不公平锁:可以插队执行(默认)
public class SaleTicketDemo02 {
//买票demo
public static void main(String[] args) {
Ticket2 ticket = new Ticket2();
new Thread(()->{for (int i = 0; i < 50; i++) ticket.sale();},"A线程").start();
new Thread(()->{for (int i = 0; i < 50; i++) ticket.sale();},"B线程").start();
new Thread(()->{for (int i = 0; i < 50; i++) ticket.sale();},"C线程").start();
}
}
class Ticket2{
private Integer number = 50;
//lock锁
Lock lock= new ReentrantLock();
public synchronized void sale(){
//加锁
lock.lock();
try{
if(number>0){
System.out.println(Thread.currentThread().getName()+"卖出了第"+number--+"张票"+"___剩余"+number);
}
}catch (Exception e){
e.printStackTrace();
}finally {
//解锁
lock.unlock();
}
}
}
synchronized和lock锁的区别
- synchronized是关键字。lock是一个接口
- synchronized无法获取锁的状态。lock可以判断是否获取到了锁
- synchroniezd是自动释放锁。lock是必须手动释放的(不释放锁就是死锁)
- synchronized会等待锁的释放获取到锁。lock锁不一定会一直等待,等不到就结束了
- synchronized可重入,不可中断,非公平锁。lock可重入,可以判断锁,可以配置为公平锁
- synchronized适合少量的代码同步问题,lock适合大量的同步代码