多线程卖票小案例
作者:互联网
多线程卖票小案例
卖票
package cn.lucky.Thread;
/**
* @author lucky
*/
public class Lucky_ticket_runnable implements Runnable{
private static int num=50;
@Override
public void run() {
for (int i = 0; i < 50; i++) {
if(num>0){
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"卖出一张票,剩余"+(--num)+"张");
}
}
}
}
测试
package cn.lucky.Thread;
/**
* @author lucky
*/
public class Test_tickets {
public static void main(String[] args) {
Lucky_ticket_runnable2 ltr = new Lucky_ticket_runnable2();
Thread lt1 = new Thread(ltr,"lt1");
Thread lt2 = new Thread(ltr,"lt2");
Thread lt3 = new Thread(ltr,"lt3");
lt1.start();
lt2.start();
lt3.start();
}
}
我们发现,出现了卖同一张票,以及卖票负数的情况,这是为什么呢?
- 首先我们分析卖同一张票的原因
- 其中--num我们可以理解为num=num-1;
- 当A线程和B线程同时进入判断条件时,假设进入时票数num=30
- A线程正在做num=这个过程,到这里阻塞了
- 此时B线程正做num=这个过程
- 此时如果不阻塞了,A线程开始做num-1,此时num=29
- 此时B线程的已经执行num=这个过程,B线程的num=30,再执行num-1,B线程的结果也为29
- 所以就出现了卖同一张票的过程
- 然后我们分析超卖的情况
- 当num=1的时候,由于线程抢占资源,A和B同时进入判断
- 此时A线程做完输出语句--num,num的值为0
- 而此时B线程还没执行输出语句,B中的num就变成了0
- 然而B线程又要执行输出语--num,此时B中的num就变成了-1
- 所以就出现了超卖的情况
那我们如何解决这个问题呢?
这个时候锁的概念就出现了
方式一:使用同步代码块
@Override
public void run() {
for (int i = 0; i < 50; i++) {
synchronized (this.getClass()){
if(num>0){
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"卖出一张票,剩余"+(--num)+"张");
}
}
}
}
方式二:使用synchronized关键字
@Override
public synchronized void run() {
for (int i = 0; i < 50; i++) {
if(num>0){
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"卖出一张票,剩余"+(--num)+"张");
}
}
}
方式三:使用锁机制
Lock l = new ReentrantLock();
@Override
public void run() {
for (int i = 0; i < 50; i++) {
//获取锁
l.lock();
try {
if (num > 0) {
System.out.println(Thread.currentThread().getName() + "卖出一张票,剩余" + (--num) + "张");
Thread.sleep(100);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
//释放锁
l.unlock();
}
}
}
结果
标签:Thread,卖票,void,案例,num,线程,--,多线程,public 来源: https://www.cnblogs.com/lucky8991/p/14551282.html