package com.ywj.Thread;
/**
* 模拟买票理解synchronized同步锁
*/
public class BuyTicket implements Runnable {
private Integer ticketNum = 50; // 票数
private boolean flag = true; // 是否有余票可买
private Object lock = new Object(); //只是用来加锁,没有其他含义
@Override
public void run() {
while (flag) {
// buyTicket0();
// buyTicket1();
// buyTicket2();
buyTicket3();
}
}
/*
票数线程不安全,不要想当然的给票加锁,这样是锁不住的,因为票数一直在变化
同步锁,锁不变的对象,不锁变的对象,可变的是对象的属性
*/
public void buyTicket0() {
//锁票数,锁不住
synchronized (ticketNum) {
if (ticketNum <= 0) {
flag = false;
return;
}
try {
Thread.sleep(100); // 模拟网络延时
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "---" + ticketNum--);
}
}
/*
锁this,类的同一实例可以锁住
假如票数属于类,也就是static修饰,类的两个不同实例访问是锁不住的,因为此时的this不同:
BuyTicket bt1 = new BuyTicket();
BuyTicket bt2 = new BuyTicket();
new Thread(bt1, "张三").start();
new Thread(bt2, "李四").start();
这时就需要加锁到类才能锁住,可以采用以下3中方式:
1.锁对象加static修饰:private static Object lock = new Object();
synchronized (lock){
}
2.方法加static修饰:
public static synchronized void buyTicket(){
}
3.锁Class对象:
synchronized(BuyTicket.class){
}
*/
public void buyTicket1() {
//锁this
synchronized (this) {
if (ticketNum <= 0) {
flag = false;
return;
}
try {
Thread.sleep(100); // 模拟网络延时
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "---" + ticketNum--);
}
}
//锁方法,就是锁this对象,同一对象可以锁住
public synchronized void buyTicket2() {
if (ticketNum <= 0) {
flag = false;
return;
}
try {
Thread.sleep(100); // 模拟网络延时
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "---" + ticketNum--);
}
/*
通过定义一个不变的Object对象来加锁,同一对象可以锁住,不同对象需要加static修饰才能锁住
*/
public void buyTicket3() {
//锁Object对象
synchronized (lock) {
if (ticketNum <= 0) {
flag = false;
return;
}
try {
Thread.sleep(100); // 模拟网络延时
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "---" + ticketNum--);
}
}
public static void main(String[] args) {
//这里都是BuyTicket 类的同一实例
BuyTicket bt = new BuyTicket();
new Thread(bt, "张三").start();
new Thread(bt, "李四").start();
new Thread(bt, "王五").start();
}
}
synchronized同步锁
最新推荐文章于 2024-07-27 13:31:57 发布