3、Lock锁(重点)
用传统的 synchronized
04-传统的Synchronized锁
1. 买票的例子
package com.hkx.demo01;
/**
* @program: juc
* @description: 买票的例子
* @author: Casey Hu
* @create: 2022-07-24 19:11
**/
/***
* 真正多线程的开发 公司中的开发
* 线程就是一个单独的资源类,没有任何附属的操作
* 1.属性 方法
*/
public class SaleTicketDemo01 {
public static void main(String[] args) {
new Thread(new MyThread()).start();
}
}
class MyThread implements Runnable{
@Override
public void run(){
}
}
2. 线程就是一个单独的资源类,没有任何附属的操作
Runnable() 属于:函数式接口@FunctionalInterface
匿名内部类 new Runable()
package com.hkx.demo01;
/**
* @program: juc
* @description: 买票的例子
* @author: Casey Hu
* @create: 2022-07-24 19:11
**/
/***
* 真正多线程的开发 公司中的开发
* 线程就是一个单独的资源类,没有任何附属的操作
* 1.属性 方法
*/
public class SaleTicketDemo01 {
public static void main(String[] args) {
//并发:多个线程操作同一个资源类,把资源类丢入线程
Ticket ticket=new Ticket(); //资源类
//函数式接口@FunctionalInterface ,jdk1.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();
}
}
//资源类 OOP开发
class Ticket{
//属性 和 方法
private int number=50;
//买票的方式
// synchronized 本质 :队列 锁
public synchronized void sale(){
if (number>0){
System.out.println(Thread.currentThread().getName()+"卖出了第"+(number--)+"张票,剩余:"+number);
}
}
}
输出日志:
"D:\Program Files (x86)\Java\jdk1.8.0_144\bin\java.exe" "-javaagent:D:\Program Files (x86)\JetBrains\IntelliJ IDEA 2022.1.3\lib\idea_rt.jar=58815:D:\Program Files (x86)\JetBrains\IntelliJ IDEA 2022.1.3\bin" -Dfile.encoding=UTF-8 -classpath "D:\Program Files (x86)\Java\jdk1.8.0_144\jre\lib\charsets.jar;D:\Program Files (x86)\Java\jdk1.8.0_144\jre\lib\deploy.jar;D:\Program Files (x86)\Java\jdk1.8.0_144\jre\lib\ext\access-bridge-64.jar;D:\Program Files (x86)\Java\jdk1.8.0_144\jre\lib\ext\cldrdata.jar;D:\Program Files (x86)\Java\jdk1.8.0_144\jre\lib\ext\dnsns.jar;D:\Program Files (x86)\Java\jdk1.8.0_144\jre\lib\ext\jaccess.jar;D:\Program Files (x86)\Java\jdk1.8.0_144\jre\lib\ext\jfxrt.jar;D:\Program Files (x86)\Java\jdk1.8.0_144\jre\lib\ext\localedata.jar;D:\Program Files (x86)\Java\jdk1.8.0_144\jre\lib\ext\nashorn.jar;D:\Program Files (x86)\Java\jdk1.8.0_144\jre\lib\ext\sunec.jar;D:\Program Files (x86)\Java\jdk1.8.0_144\jre\lib\ext\sunjce_provider.jar;D:\Program Files (x86)\Java\jdk1.8.0_144\jre\lib\ext\sunmscapi.jar;D:\Program Files (x86)\Java\jdk1.8.0_144\jre\lib\ext\sunpkcs11.jar;D:\Program Files (x86)\Java\jdk1.8.0_144\jre\lib\ext\zipfs.jar;D:\Program Files (x86)\Java\jdk1.8.0_144\jre\lib\javaws.jar;D:\Program Files (x86)\Java\jdk1.8.0_144\jre\lib\jce.jar;D:\Program Files (x86)\Java\jdk1.8.0_144\jre\lib\jfr.jar;D:\Program Files (x86)\Java\jdk1.8.0_144\jre\lib\jfxswt.jar;D:\Program Files (x86)\Java\jdk1.8.0_144\jre\lib\jsse.jar;D:\Program Files (x86)\Java\jdk1.8.0_144\jre\lib\management-agent.jar;D:\Program Files (x86)\Java\jdk1.8.0_144\jre\lib\plugin.jar;D:\Program Files (x86)\Java\jdk1.8.0_144\jre\lib\resources.jar;D:\Program Files (x86)\Java\jdk1.8.0_144\jre\lib\rt.jar;E:\IdeaProjects\juc\juc\target\classes;D:\Maven\repository\org\projectlombok\lombok\1.18.8\lombok-1.18.8.jar" com.hkx.demo01.SaleTicketDemo01
A卖出了第50张票,剩余:49
A卖出了第49张票,剩余:48
A卖出了第48张票,剩余:47
B卖出了第47张票,剩余:46
B卖出了第45张票,剩余:44
B卖出了第44张票,剩余:43
A卖出了第46张票,剩余:45
A卖出了第42张票,剩余:41
A卖出了第41张票,剩余:40
A卖出了第40张票,剩余:39
A卖出了第39张票,剩余:38
A卖出了第38张票,剩余:37
B卖出了第43张票,剩余:42
B卖出了第35张票,剩余:34
B卖出了第34张票,剩余:33
B卖出了第33张票,剩余:32
B卖出了第32张票,剩余:31
B卖出了第31张票,剩余:30
B卖出了第30张票,剩余:29
B卖出了第29张票,剩余:28
B卖出了第28张票,剩余:27
B卖出了第27张票,剩余:26
B卖出了第26张票,剩余:25
B卖出了第25张票,剩余:24
B卖出了第24张票,剩余:23
B卖出了第23张票,剩余:22
B卖出了第22张票,剩余:21
B卖出了第21张票,剩余:20
B卖出了第20张票,剩余:19
B卖出了第19张票,剩余:18
B卖出了第18张票,剩余:17
B卖出了第17张票,剩余:16
B卖出了第16张票,剩余:15
B卖出了第15张票,剩余:14
B卖出了第14张票,剩余:13
B卖出了第13张票,剩余:12
B卖出了第12张票,剩余:11
A卖出了第36张票,剩余:35
A卖出了第10张票,剩余:9
A卖出了第9张票,剩余:8
A卖出了第8张票,剩余:7
A卖出了第7张票,剩余:6
A卖出了第6张票,剩余:5
A卖出了第5张票,剩余:4
A卖出了第4张票,剩余:3
A卖出了第3张票,剩余:2
A卖出了第2张票,剩余:1
A卖出了第1张票,剩余:0
C卖出了第37张票,剩余:36
B卖出了第11张票,剩余:10
进程已结束,退出代码0
05-Lock锁
Lock 接口
Lock接口的三个实现类
SaleTicketDemo02
公平锁:处理线程公平,先来后到
非公平锁:处理线程不公平,根据CPU资源可以插队(默认非公平锁)
package com.hkx.demo01;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/**
* @program: juc
* @description: 卖票的例子
* @author: Casey Hu
* @create: 2022-07-25 21:55
**/
public class SaleTicketDemo02 {
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
class Ticket2 {
private int number = 50;
Lock lock = new ReentrantLock();
/***
* 1.new ReentrantLock()
* 2.lock(); 加锁
* 3.unlock(); 解锁
*/
public void sale() {
lock.lock(); //加锁
try {
//业务代码
if (number > 0) {
System.out.println(Thread.currentThread().getName() + "卖出了第" + (number--) + "张票,剩余:" + number);
}
} finally {
lock.unlock(); //解锁
}
}
}
Synchronized和Lock 的区别是什么
06-Synchronized和Lock区别
1、Synchronized 内置的java关键字,Lock是一个Java类
2、Synchronized 无法判断锁的状态,Lock可以判断是否获取到了锁
3、Synchronized 是全自动的 会自动释放锁 (a线程执行完就自动释放,b线程出现异常也会被释放)Lock 必须要手动释放锁!如果不释放就会死锁
4、Synchronized 线程1(获得锁,阻塞了),线程2(等待,一直等);Lock锁就不一定会等待下去;
lock.tryLock();//尝试获取锁
5、Synchronized 可重入锁,不可中断的,非公平;Lock,可重入锁,可以判断,非公平(可以自己设置)
6、Synchronized 适合锁少量的代码同步问题,Lock适合锁大量的同步代码!