对于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.将外部的引入的 ...
随机推荐
- 【agc008F】Black Radius
Portal --> agc008F Solution 这题好神仙啊qwq疯狂orz看懂日文题解的sjk太强啦qwq 首先我们要统计的东西,是一个涂黑的连通块,然后我们考虑找一个 ...
- windows使用composer.phar
把composer.phar复制到php安装目录下, 新建一个composer.bat文件,编辑 @php "%~dp0composer.phar" %* 保存,然后就可以使用co ...
- win7 64位环境下配置汇编环境和程序设计
下载dosbox,并解压安装 下载地址: http://pan.baidu.com/s/1eRJbJAq 默认安装到C:\Program Files (x86)\DOSBox-0.74 安装成功后,双 ...
- Bootstrap笔记-加强版
1.bootstrap引入: <!DOCTYPE html><html lang="zh-cn"><head><meta charset= ...
- oracle的小语句
select * from v$nls_parameters; 查询数据库中现在的常量 alter session set NLS_DATE_FORMAT='yyyy-mm-dd'; 更改日期显示方式
- Android 加载网络图片设置到ImageView
下载图片后显示在ImageView中 //1.定义全局变量 private Handler handler; private String image_url; private Bitmap bitm ...
- web开发之Servlet 二
在上一篇文章中,我们演示也证明了Servlet 是一种动态web资源开发的技术,即我可以在浏览器中输入URL,然后就可以在浏览器中看到我们编写的Servlet资源. 那当我们在浏览器上一起一个HTTP ...
- DHTML中window的使用
window对象是对浏览器窗口进行操作的对象.以下列出一些常用的对象(三级为对象的方法.属性) |-navigator:是对浏览器信息进行操作的对象 |-history:包含用户浏览过的url信息 | ...
- 【BZOJ】1087: [SCOI2005]互不侵犯King
[算法]状态压缩型DP [题解]http://www.cnblogs.com/xtx1999/p/4620227.html (orz) https://www.cnblogs.com/zbtrs/p/ ...
- phpStudy 虚拟主机
转载:http://blog.csdn.net/sinat_35861664/article/details/53557574 windows下配置虚拟主机,实现多域名访问本地项目目录 1.Apach ...