对于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.将外部的引入的 ...
随机推荐
- 【agc004C】AND Grid
Portal --> agc004C Description 给你一个\(n*m\)的网格图\(A\),有一些格子是'#',现在要构造出两个新的网格图\(B\)和\(C\)满足: 1.如果\(A ...
- Howto run google-chrome as root
Just want to add a permanent solution to the problem: 1. Open google-chrome located in /usr/bin with ...
- Python3 字典 get() 方法
Python3 字典 描述 Python 字典 get() 函数返回指定键的值,如果值不在字典中返回默认值. 语法 get()方法语法: dict.get(key, default=None) 参数 ...
- Overlaying GPS Coordinates for Camera Crosshairs
Hey Guys! I am working on a project to allow us to implement GPS coordinates for the location of the ...
- python如何优雅判断类型
http://note.youdao.com/noteshare?id=6f3a7963efc57b5d0b1c712654d100c6
- openstack日志模块
一.简单的python日志模块介绍 http://www.cnblogs.com/tuzkee/p/3974193.html http://blog.csdn.net/jgood/article/de ...
- 816E. Karen and Supermarket 树形DP
LINK 题意:给出n个商品,除第一个商品外,所有商品可以选择使用优惠券,但要求其前驱商品已被购买,问消费k以下能买几个不同的商品 思路:题意很明显就是树形DP.对于一个商品有三种选择,买且使用优惠券 ...
- linux中execve函数的用法
在父进程中fork一个子进程,在子进程中调用exec函数启动新的程序.exec函数一共有六个,其中execve为内核级系统调用,其他(execl,execle,execlp,execv,execvp) ...
- selenium.common.exceptions.ElementNotVisibleException: Message: element not visible处理方法:selenium针对下拉菜单事件的处理
使用Selenium爬虫时,可能会遇到一些下拉菜单,动态加载,如果直接使用find_element_by_函数会报错,显示selenium.common.exceptions.ElementNotVi ...
- 简单高效的asp.net目录树源代码
前台页面: <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default. ...