卖票代码(最初的样子)
class TicketForNoSychronized{
//买了多少张?
private static Integer saledNum = 0;
//还剩多少张?50张!!!
private static Integer lastedNum = 50;
//注意此处方法为最最最最普通的方法---卖票
public void sale() {
//卖之前判断一下剩的票是否大于0
if(lastedNum>0) {
//睡眠300毫秒=业务员在操作收钱打票
try {
//超级好用的TimeUnit
TimeUnit.MICROSECONDS.sleep(300);
} catch (InterruptedException e) {
e.printStackTrace();
}
//醒来(一切还是当初的样子吗)=业务员买完了,调整下库存
//剩余的票减少一张
lastedNum--;
//卖出的票加一张
saledNum++;
//给我们看看结果
System.out.println(
Thread.currentThread().getName()
+"线程卖出了"+saledNum
+"还剩"+lastedNum+"张票");
}
}
}
执行卖票的代码(多线程,来两个窗口卖票)
public class testNoSychronized {
public static void main(String[] args) {
//首先你得有个卖票站点,我们亲切地称它为对象,(此时为实例对象)
TicketForNoSychronized object =
new TicketForNoSychronized();
//创建个A线程,重写个run方法,并开启执行(此处为潮流的lambda表达式)
new Thread(()->{
//怎么执行?---->执行55次卖票,当然,卖没了就不卖是在卖票代码里给我保证的
for (int i = 0;i<55;i++) {
object.sale();
}
},"A").start();
//同样,窗口2 ,同时干!
new Thread(()->{
for (int i = 0;i<55;i++) {
object.sale();
}
},"B").start();
}
}
结果:
不但卖超了,而且怎么没有还剩3张票的记录?怎么还剩2张报告了2次?
我是卖票站点的老板,我反思:
- 执行没问题,一个站点,两个窗口同时卖。(执行方法不变)
- 把这个票加锁,让这两个窗口依次有序执行卖票。(站点整顿改变)
华丽的分割线 华丽的分割线 华丽的分割线 华丽的分割线 华丽的分割线 华丽的分割线
卖票代码(加锁变身术一)
class TicketForNoSychronized{
//不变
private static Integer saledNum = 0;
//不变
private static Integer lastedNum = 50;
//变//此处加个synchronized//
public synchronized void sale() {
//不变
if(lastedNum>0) {
//不变
try {
//不变
TimeUnit.MICROSECONDS.sleep(300);
} catch (InterruptedException e) {
e.printStackTrace();
}
//不变
lastedNum--;
//不变
saledNum++;
//不变
System.out.println(
Thread.currentThread().getName()
+"线程卖出了"+saledNum
+"还剩"+lastedNum+"张票");
}
}
}
结果:
多次试验结果都很合心意,如我所愿
并发编程如果到这里就结束了该多好呢。。。
我是卖票站点的老板,我反思:
有些人因为贪婪,想得更多的东西,却把现在所有的也失掉了。 ——伊索
- 站点稳定了,再开家连锁店吧 (执行方法里创建两个对象)
- 在连锁店开两个窗口(执行方法里增加创建两个线程)
- 票永远是这50张(扩大供货指日可待)(卖票的那一套不变)
华丽的分割线 华丽的分割线 华丽的分割线 华丽的分割线 华丽的分割线 华丽的分割线
执行卖票的代码(俩对象变身术A)
public class testNoSychronized {
public static void main(String[] args) {
//首先你得有个卖票站点,我们亲切地称它为对象,(此时为实例对象)
TicketForNoSychronized object =
new TicketForNoSychronized();
变
TicketForNoSychronized object2 =
new TicketForNoSychronized();
//不变
new Thread(()->{
//怎么执行?---->执行55次卖票,当然,卖没了就不卖是在卖票代码里给我保证的
for (int i = 0;i<55;i++) {
object.sale();
}
},"A").start();
//不变
new Thread(()->{
for (int i = 0;i<55;i++) {
object.sale();
}
},"B").start();
//新增1号
new Thread(()->{
for (int i = 0;i<55;i++) {
object2.sale();
}
},"1号").start();
//新增2号
new Thread(()->{
for (int i = 0;i<55;i++) {
object2.sale();
}
},"2号").start();
}
}
结果:
很显然一切都回到最初那个样子混乱了
我是卖票站点的老板,我反思:
- 执行没问题,2个站点,四个窗口同时卖那50张。(执行方法不变)
- 把这个票加锁,让这两个窗口依次有序执行卖票。(站点整顿改变)
华丽的分割线 华丽的分割线 华丽的分割线 华丽的分割线 华丽的分割线 华丽的分割线
卖票代码(加锁+加静 变身术二)
class TicketForNoSychronized{
//不变
private static Integer saledNum = 0;
//不变
private static Integer lastedNum = 50;
//变//此处加个synchronized再加个static//
public static synchronized void sale() {
//不变
if(lastedNum>0) {
//不变
try {
//不变
TimeUnit.MICROSECONDS.sleep(300);
} catch (InterruptedException e) {
e.printStackTrace();
}
//不变
lastedNum--;
//不变
saledNum++;
//不变
System.out.println(
Thread.currentThread().getName()
+"线程卖出了"+saledNum
+"还剩"+lastedNum+"张票");
}
}
}
番外篇:这个static加在synchronized前和后都可以,具体为什么?不知道
结果:
很显然一切都好起来了
我是卖票站点的老板,我反思:
- 满足了最基本的业务扩张
具体原理,且听下回分说
今天的文章java多线程买票例子_多线程解决窗口售票问题「建议收藏」分享到此就结束了,感谢您的阅读。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/89045.html