多个线程之间共享数据,(探究)一下十一的车票是怎么卖的
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了多个线程之间共享数据,(探究)一下十一的车票是怎么卖的相关的知识,希望对你有一定的参考价值。
十月一到了,大家有没有抢到回家的车票。笔者有事退了回家的卧铺票,今年十一就不回家了。算下来有8个多月没有回家了,混沌之余想想抢票是怎么回事吧。为什么会有许多的抢票软件,还有12306发售的,还有售票窗口发售的。就不会卖重吗?
题设来了:现在剩下1000张票了,有的地方在买票、有的还像笔者一样退了票。其实归根结底,我们操作的都是12306的共享数据那1000张票。
在这里不得不讲解一下,一个关键的地方:
synchronized 关键字,代表这个方法加锁
也就是说当线程运行到这个方法的时候,就开始检查有没有其他线程正在使用这个方法,有的话就等待其他线程运行完毕,没有的话就自己运行(好像很绅士的样子,你先上,你请,最后在自己上)。笔者在想,当我看到有票慌忙填数据提交完买票之后,浏览器开始刷新,刷了一小会之后告诉我“票已经卖空了”,应该就是synchronized的锅吧。
synchronized关键字最主要有以下3种应用方式
修饰实例方法,作用于当前实例加锁,进入同步代码前要获得当前实例的锁
修饰静态方法,作用于当前类对象加锁,进入同步代码前要获得当前类对象的锁
修饰代码块,指定加锁对象,对给定对象加锁,进入同步代码库前要获得给定对象的锁。
这里只是一个简单的售票原理。真实情况肯定不会这么的简单,但简单又可以罗列出复杂。
贴出简单原理:
package com.css.java.learning.ticket;
/**
* 探究火车票的售卖原理
* @author Red_Ant
* 20180928
*/
public class SaleTrainTicket {
private int totalCount = 1000;//通过什么途径获得的数据,笔者不管。反正就1000张票。
//卖票
public synchronized int SaleTicket(int num) {
totalCount = totalCount - num;
return totalCount;
}
//退票
public synchronized int RebackTicket(int num) {
if(totalCount < 0) {
totalCount = 0;
}
totalCount = totalCount + num;
return totalCount;
}
}
接下来就是各个售票部分的调用,有的卖票,有的办理退票。简单的调用代码:
SaleTrainTicket manager = new SaleTrainTicket();
new Thread(new Runnable() {
@Override
public void run() {
int leaveNum = manager.SaleTicket(2);
if(leaveNum <= 0) {
System.err.println("呵呵,已经没票了");;
}else {
System.err.println("还有" + leaveNum + "张票");
}
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
int num = manager.RebackTicket(1);
System.err.println("退票之后,还有" + num + "张");
}
}).start();
}
【后话】
像数据共享这块,肯定不是笔者这样的简单操作。得是共享数据库数据吧!
我想原理差不多就这样吧。
运行的一个小效果:
以上是关于多个线程之间共享数据,(探究)一下十一的车票是怎么卖的的主要内容,如果未能解决你的问题,请参考以下文章