对于JAVA多线程卖票小程序的理解
昨天把多线程重新看了一遍,发现自己还是有许多需要理解的地方,现在写一篇总结。
一:利用继承Thread类会出现的问题:
public class SellTicketsThread extends Thread {
private int tickets = 10;
public SellTicketsThread(String name) {
super(name);
}
@Override
public void run() {
while (true) {
if(tickets<=0) break;
synchronized (this) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
if (tickets > 0) {
System.out.println(Thread.currentThread().getName() + "卖出第"
+ tickets-- + "张票");
}
}
}
}
}
public class SellTicketsThreadDemo {
public static void main(String[] args) {
SellTicketsThread t1 = new SellTicketsThread("窗口1");
SellTicketsThread t2 = new SellTicketsThread("窗口2");
SellTicketsThread t3 = new SellTicketsThread("窗口3");
t1.start();
t2.start();
t3.start();
}
}
这样的话看上去是用了同步锁锁住了对象,但运行结果却是不符合逻辑的。三个窗口共卖了30张票。
窗口2卖出第10张票
窗口1卖出第10张票
窗口3卖出第10张票
窗口3卖出第9张票
窗口2卖出第9张票
窗口1卖出第9张票
窗口3卖出第8张票
窗口1卖出第8张票
窗口2卖出第8张票
窗口2卖出第7张票
窗口3卖出第7张票
窗口1卖出第7张票
窗口2卖出第6张票
窗口1卖出第6张票
窗口3卖出第6张票
窗口2卖出第5张票
窗口1卖出第5张票
窗口3卖出第5张票
窗口2卖出第4张票
窗口3卖出第4张票
窗口1卖出第4张票
窗口2卖出第3张票
窗口1卖出第3张票
窗口3卖出第3张票
窗口2卖出第2张票
窗口1卖出第2张票
窗口3卖出第2张票
窗口2卖出第1张票
窗口3卖出第1张票
窗口1卖出第1张票
二:利用Runnale接口实现
package SellTickets;
public class SellTicketsThread implements Runnable{
private int tickets = 10;
@Override
public void run() {
while(true){
if(tickets<=0) break;
synchronized(this){
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
if(tickets>0){
System.out.println(Thread.currentThread().getName()+"卖出第"+tickets--+"张票");
}
}
}
}
}
public class SellTicketsThreadDemo {
public static void main(String[] args) {
SellTicketsThread st = new SellTicketsThread();
Thread t1 = new Thread(st,"窗口一");
Thread t2 = new Thread(st,"窗口二");
Thread t3 = new Thread(st,"窗口三");
t1.start();
t2.start();
t3.start();
}
}
窗口一卖出第10张票
窗口一卖出第9张票
窗口一卖出第8张票
窗口三卖出第7张票
窗口二卖出第6张票
窗口二卖出第5张票
窗口三卖出第4张票
窗口三卖出第3张票
窗口三卖出第2张票
窗口三卖出第1张票
这样就不会有问题了,因为三个线程共享的是同一个Runnable开辟的内存.网上几乎都是用的这种方法,能不能不用Runnable接口也能实现这个效果呢??接下来是用Thread实现的两种方式,如有错误之处还请指正.
三:在继承Thread的类中定义静态变量和静态方法,将锁加在静态方法上,让多个线程共享。
public class SellTicketsThread extends Thread {
public SellTicketsThread(String name){
super(name);
}
public SellTicketsThread(){
}
private static int tickets =10;
public synchronized static void take(){
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
if(tickets>0){
System.out.println(Thread.currentThread().getName() + "卖出第"
+ tickets-- + "张票");
}
}
@Override
public void run() {
while(true){
take();
}
}
}
public class SellTicketsThreadDemo {
public static void main(String[] args) {
SellTicketsThread t1 = new SellTicketsThread("窗口1");
SellTicketsThread t2 = new SellTicketsThread("窗口2");
SellTicketsThread t3 = new SellTicketsThread("窗口3");
t1.start();
t2.start();
t3.start();
}
}
窗口1卖出第10张票
窗口1卖出第9张票
窗口3卖出第8张票
窗口3卖出第7张票
窗口3卖出第6张票
窗口2卖出第5张票
窗口2卖出第4张票
窗口3卖出第3张票
窗口1卖出第2张票
窗口1卖出第1张票
四:定义一个锁对象,让多个线程共同用同一个锁,同时将共享变量定义成静态的。
public class SellTicketsThread extends Thread {
Object o =null;
private static int tickets = 10;
public SellTicketsThread(String name,Object o){
super(name);
this.o = o;
}
public SellTicketsThread(){
}
@Override
public void run() {
while(true){
while(true){
if(tickets<=0) break;
synchronized(o){
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
if(tickets>0){
System.out.println(Thread.currentThread().getName()+"卖出第"+tickets--+"张票");
}
}
}
}
}
}
public class SellTicketsThreadDemo {
public static void main(String[] args) {
Object o = new Object();//共同的锁
SellTicketsThread t1 = new SellTicketsThread("窗口1",o);
SellTicketsThread t2 = new SellTicketsThread("窗口2",o);
SellTicketsThread t3 = new SellTicketsThread("窗口3",o);
t1.start();
t2.start();
t3.start();
}
}
窗口1卖出第10张票
窗口1卖出第9张票
窗口1卖出第8张票
窗口3卖出第7张票
窗口3卖出第6张票
窗口3卖出第5张票
窗口3卖出第4张票
窗口2卖出第3张票
窗口2卖出第2张票
窗口2卖出第1张票
还需要注意的是,同步代码块的锁对象是任意对象。所以可以用Object做为一个锁。而同步方法(非静态)的锁对象是 this。静态方法的锁对象是类的字节码文件对象。
对于JAVA多线程卖票小程序的理解的更多相关文章
- java多线程实现卖票小程序
package shb.java.demo; /** * 多线程测试卖票小程序. * @Package:shb.java.demo * @Description: * @author shaobn * ...
- Java多线程卖票例子
package com.test; public class SaleTickets implements Runnable { private int ticketCount = 10;// 总的票 ...
- Java之——实现微信小程序加密数据解密算法
转载请注明出处:http://blog.csdn.net/l1028386804/article/details/79450115 一.概述 微信推出了小程序,很多公司的客户端应用不仅具有了APP.H ...
- Java实现卖票程序(两种线程实现)
/** * 2019年8月8日16:05:05 * 目的:实现火车站卖票系统(第一种创建线程的方式) * @author 张涛 * */ //第一种方式直接继承Thread来创建线程 class T1 ...
- java服务端微信小程序支付
发布时间:2018-10-05 技术:springboot+maven 概述 java微信小程序demo支付只需配置支付一下参数即可运行 详细 代码下载:http://www.demodash ...
- 「小程序JAVA实战」微信小程序工程结构了解(五)
转自:https://idig8.com/2018/08/09/xiaochengxu-chuji-05/ 微信小程序工程结构 audio,button,canvas,checkbox 都是由4个文件 ...
- 「小程序JAVA实战」微信小程序简介(一)
转自:https://idig8.com/2018/08/09/xiaochengxu-chuji-01/ 一直想学习小程序,苦于比较忙,加班比较多没时间,其实这都是理由,很多时候习惯了搬砖,习惯了固 ...
- JAVA编写的断点续传小程序
上了一周的课,今天终于可以休息了,太棒了,今天闲着无聊使用java语言写了一个断点续传的小程序来分享给大家, 首先要下载个用于网络请求的框架:我这里给出地址,是用的Apache的HttpClient: ...
- java后台获取微信小程序openid
一.jar包准备 1.在网盘下载 链接:https://pan.baidu.com/s/15HAAWOg_yn768g4s9IrcPg 提取码:hgj0 二.在pom文件中添加依赖 1.将外部的引入的 ...
随机推荐
- 洛谷 P2530 [SHOI2001]化工厂装箱员 解题报告
P2530 [SHOI2001]化工厂装箱员 题目描述 118号工厂是世界唯一秘密提炼锎的化工厂,由于提炼锎的难度非常高,技术不是十分完善,所以工厂生产的锎成品可能会有3种不同的纯度,A:100%,B ...
- Linux(五)shell编程基础
一.Linux shell简介 1.shell概述 Shell 是用户与内核进行交互操作的一种接口,目前最流行的 Shell 称为 bash Shell Shell 是一门编程语言& ...
- 金牌架构师:我们是这样设计APP数据统计产品的
前言:近期,智能大数据服务商“个推”推出了应用统计产品“个数”,今天我们就和大家来谈一谈个数实时统计与AI数据智能平台整合架构设计. 很多人可能好奇,拥有数百亿SDK的个推,专注消息推送服务多年,现在 ...
- Java中关于Arrays.asList方法的深入学习与理解
Java的标准库中在java.util包下提供了很多实用的工具类,如:Arrays,Collections等工具类都提供了一些比较实用的方法.在实际的开发使用中,我们经常需要使用这样的需求:将一个数组 ...
- JS常用面试题
一.闭包: 1.函数嵌套函数.内部函数可以引用外部函数的参数和变量. 参数和变量不会被垃圾回收机制所收回 function aaa(a){ var b = 5; function bbb(){ ...
- Linux高级编程--04.GDB调试程序(入门概述)
GDB概述 GDB是GNU开源组织发布的一个强大的UNIX下的程序调试工具.或许,各位比较喜欢那种图形界面方式的,像VC.BCB等IDE的调试,但如果你是在UNIX平台下做软件,你会发现GDB这个调试 ...
- Zepto学习笔记
Zepto和jQuery的很多API都很一致,思路也很相似,我不会全都整理出来,只是把一些平时用到了的或者不同的地方需要注意一下的地方总结出来.另外,Zepto现在还不是很成熟,无论是对大小写的敏感还 ...
- 网络流入门--最大流算法Dicnic 算法
感谢WHD的大力支持 最早知道网络流的内容便是最大流问题,最大流问题很好理解: 解释一定要通俗! 如右图所示,有一个管道系统,节点{1,2,3,4},有向管道{A,B,C,D,E},即有向图一张. ...
- 【CodeForces】908 E. New Year and Entity Enumeration
[题目]E. New Year and Entity Enumeration [题意]给定集合T包含n个m长二进制数,要求包含集合T且满足以下条件的集合S数:长度<=m,非和与的结果都在集合中. ...
- Vue 使用自定义组件时报错:Uncaught TypeError: Cannot assign to read only property 'exports' of object '#<Object>'
自己试做了一下vue的插件 参考element-ui: 写了一个组件 import message from './packages/message/index.js'; const install ...