学习目标:
java 多线程资源锁
学习内容:
生产者和消费者模型
学习时间:
20220318
1、临界资源-案例
2、资源锁:同步代码块、同步方法、显示锁
学习产出:
临界资源 问题demo
//临界资源问题 2022-03-15 gugq
//典型案例:售票问题
public class CriticalResourceDemo{
static int count = 100; //票数
static int number = 0; //售票顺序
// static Object aa = new Object(); //用于作 对象锁
static Runnable r = new Runnable(){ //target
//------------------------------ 同步代码块 --------------------------------------------------
@Override
public void run(){
while(count > 0){
synchronized(" "){//对象锁 任意的对象都可以充当一把锁
if(count <= 0) return; //
number++;
count--;
System.out.println("售票员 " + Thread.currentThread().getName() +
" 卖出了第 " + number + " 张票,剩余 " + count + " 张");
}
try {
Thread.sleep(10); //大家都有的卖
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
//------------------------------- 同步方法(隐式)-------------------------------------------------
// @Override
// public void run(){
// while(count > 0){
// sellTickets();
// try {
// Thread.sleep(10); //大家都有的卖
// } catch (InterruptedException e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
// }
// }
// }
// public synchronized void sellTickets(){ //同步方法
// if(count <= 0) return;
// number++;
// count--;
// System.out.println("售票员 " + Thread.currentThread().getName() +
// " 卖出了第 " + number + " 张票,剩余 " + count + " 张");
// }
//
};
public static void main(String[] args){
/**
* Thread(Runnable target, String name) 分配新的Thread 对象
*/
Thread t0 = new Thread(r, "张三");
Thread t1 = new Thread(r, "李四");
Thread t2 = new Thread(r, "王五");
Thread t3 = new Thread(r, "赵六");
t0.start();
t1.start();
t2.start();
t3.start();
}
}
显示锁调用demo
import java.util.concurrent.locks.ReentrantLock;
public class ReetrantLockUseDemo {
//存
static Runnable r0 = new Runnable(){
public void run(){
Card card = Card.getInstance();
while(true){
card.store(500);
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
};
//取
static Runnable r1 = new Runnable(){
public void run(){
Card card = Card.getInstance();
while(true){
card.getMoney(500);
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
};
public static void main(String[] args) {
// TODO 需求:有一张银行卡,假设初始的余额为1000,两个人存钱,每次存500;两个人取钱,每次500
/* 分析
* 临界资源:银行卡
* 不管式存还是取,需要控制当前访问的银行卡的只有一个人
*/
Thread t0 = new Thread(r0, "张三");
Thread t1 = new Thread(r0, "李四");
t0.start();
t1.start();
Thread t2 = new Thread(r1, "王五");
Thread t3 = new Thread(r1, "赵六");
Thread t4 = new Thread(r1, "小二");
t2.start();
t3.start();
t4.start();
}
}
//银行卡类 -- 单例!
class Card{
private int rest = 1000; //余额
private static Card instance = new Card();
//创建一个锁的对象
ReentrantLock lock = new ReentrantLock();
public int getRest(){
return rest;
}
private Card(){}
public static Card getInstance(){
return instance;
}
//存
public void store(int num){
lock.lock();
rest += num;
System.out.println(Thread.currentThread().getName()+"存了 "+ num +
",当前余额:" + rest);
lock.unlock();
}
//取
public void getMoney(int num){
lock.lock();
if(rest < num) num = rest; //余额不够,默认取空
rest -= num;
System.out.println(Thread.currentThread().getName()+"取了 "+ num +
",当前余额:" + rest);
lock.unlock();
}
}
学习来源:
https://edu.csdn.net/course/detail/26193