昨天把多线程重新看了一遍,发现自己还是有许多需要理解的地方,现在写一篇总结。

  一:利用继承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多线程卖票小程序的理解的更多相关文章

  1. java多线程实现卖票小程序

    package shb.java.demo; /** * 多线程测试卖票小程序. * @Package:shb.java.demo * @Description: * @author shaobn * ...

  2. Java多线程卖票例子

    package com.test; public class SaleTickets implements Runnable { private int ticketCount = 10;// 总的票 ...

  3. Java之——实现微信小程序加密数据解密算法

    转载请注明出处:http://blog.csdn.net/l1028386804/article/details/79450115 一.概述 微信推出了小程序,很多公司的客户端应用不仅具有了APP.H ...

  4. Java实现卖票程序(两种线程实现)

    /** * 2019年8月8日16:05:05 * 目的:实现火车站卖票系统(第一种创建线程的方式) * @author 张涛 * */ //第一种方式直接继承Thread来创建线程 class T1 ...

  5. java服务端微信小程序支付

    发布时间:2018-10-05   技术:springboot+maven   概述 java微信小程序demo支付只需配置支付一下参数即可运行 详细 代码下载:http://www.demodash ...

  6. 「小程序JAVA实战」微信小程序工程结构了解(五)

    转自:https://idig8.com/2018/08/09/xiaochengxu-chuji-05/ 微信小程序工程结构 audio,button,canvas,checkbox 都是由4个文件 ...

  7. 「小程序JAVA实战」微信小程序简介(一)

    转自:https://idig8.com/2018/08/09/xiaochengxu-chuji-01/ 一直想学习小程序,苦于比较忙,加班比较多没时间,其实这都是理由,很多时候习惯了搬砖,习惯了固 ...

  8. JAVA编写的断点续传小程序

    上了一周的课,今天终于可以休息了,太棒了,今天闲着无聊使用java语言写了一个断点续传的小程序来分享给大家, 首先要下载个用于网络请求的框架:我这里给出地址,是用的Apache的HttpClient: ...

  9. java后台获取微信小程序openid

    一.jar包准备 1.在网盘下载 链接:https://pan.baidu.com/s/15HAAWOg_yn768g4s9IrcPg 提取码:hgj0 二.在pom文件中添加依赖 1.将外部的引入的 ...

随机推荐

  1. [学习笔记]搜索——模拟与dp的结合

    搜索: 一种基础的算法. 考察常见于NOIP 但是高级的搜索算法可能还会在省选出现. 50%以上的暴力都可以用搜索直接枚举来写. 但是,当数据规模不是很大的时候,搜索也可能成为正解. (比如剪枝PK状 ...

  2. Linux之Makefile20160707

    说一下LINUX下的Makefile,直接根据实际碰到的Makefile进行解读: 当make的目标为all时,-C $(KDIR) 指明跳转到内核源码目录下读取那里的Makefile:M=$(PWD ...

  3. CentOS 7网络故障

    By francis_hao    Nov 2,2017   在像往常一样打开了虚拟机后,打开xshell准备连接到centos,可是连不上,发现连接的网卡没有启动,使用systemctl启动netw ...

  4. Educational Codeforces Round 20 C 数学/贪心/构造

    C. Maximal GCD time limit per test 1 second memory limit per test 256 megabytes input standard input ...

  5. Codeforces 894.B Ralph And His Magic Field

    B. Ralph And His Magic Field time limit per test 1 second memory limit per test 256 megabytes input ...

  6. STL源码分析-hashtable

    http://note.youdao.com/noteshare?id=5c8d2b09c0f72af9a12b0ed2023a338d

  7. oracle,sqlserver,mysql常见数据库jdbc连接

    发现JDBC连接字符串总是容易忘记,特此整理一下常用的几种数据的连接 ORACLE: /** * ORACLE * */ public static Connection getOracleConne ...

  8. 如何识别字符串是否是UTF-8编码的

    我们先要弄明白原始字符串里的字符用的是何种编码方式,运行如下 string tmp = "你好world"; for(int i=0;i<tmp.size();++i) { ...

  9. CF832 D LCA倍增 裸

    有询问$a,b,c$,求a到c路径上,同时是a到b路径的点的个数.其中询问中的a,b,c可任意选择作为起点或终点,求一组询问中最大值. LCA用于计算树上点对间距离,对于一组询问求深度最大的点作为起点 ...

  10. unZip/Zip的安装

    1.apt-get安装: apt-get install zip 2.yum安装: yum install -y unzip zip