对于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。静态方法的锁对象是类的字节码文件对象。

时间: 2024-08-06 15:58:41

对于JAVA多线程卖票小程序的理解的相关文章

java多线程实现卖票小程序

1 package shb.java.demo; 2 /** 3 * 多线程测试卖票小程序. 4 * @Package:shb.java.demo 5 * @Description: 6 * @author shaobn 7 * @Date 2015-9-2下午7:49:53 8 */ 9 public class TestSyn { 10 public static void main(String[] args) { 11 //此注释为实现方式一 12 /*TicketDemo td = n

Java多线程卖票例子

1 package com.test; 2 3 public class SaleTickets implements Runnable 4 { 5 private int ticketCount = 10;// 总的票数 6 Object mutex = new Object();// 锁 7 8 /** 9 * 卖票 10 */ 11 public void sellTicket() 12 { 13 synchronized (mutex)// 当操作的是共享数据时, 14 // 用同步代码

卖票小程序(二):解决Thread线程安全隐患!

第二篇文章内容 class Ticket implements Runnable//extends Thread//实现Runnable接口 { public int tic = 100; Object obj = new Object(); public void run() { while(true)//默认为真 { synchronized(obj)//同步代码块 { if(tic>0) {//如果票数大于0则执行如下代码. try {Thread.sleep(10);} catch (E

java版的QQ小程序

转载自:http://blog.csdn.net/lihongxun945/article/details/6114290 这是一个简单的java版的QQ小程序. 包括一个简单的服务器和一个简单的客户端. 运行时,先运行服务器,然后在运行客户端,就可以进行聊天了. 默认的配置是localhost,端口4545,更改ip就可以在两天电脑上进行聊天了. 目前不支持内网和外网之间的访问,也不支持多人聊天. 因为这只是一个简单的例子,感兴趣的同学可以通过改进,实现多人聊天和内外网之间的访问. 效果图:

Java Static关键字之小程序

对于学习static我们先来看两个例子: 1 public class Cat { 2 private static int sid = 0; 3 private String name; 4 int id; 5 Cat(String name) { 6 this.name = name; 7 id = sid++; 8 } 9 public void info(){ 10 System.out.println 11 ("My name is "+name+" No.&quo

抢票小程序

抢票小程序 我们可以利用所学的内容来写一个简易的抢票小程序 from multiprocessing import Process import json,time,os def search(): time.sleep(1) # 模拟网络io with open('db.txt',mode='rt',encoding='utf-8') as f: res = json.load(f) print(f'还剩{res["count"]}') def get(): with open('d

java火车站卖票程序(线程等待)

1 package com.java.thread.synch; 2 3 /** 4 * 卖票演示 5 * @author Administrator 6 * 两个车站卖100张票 7 */ 8 public class SellTicket { 9 static Object obj=new Object(); 10 static int Count=100; 11 public static void main(String[] args){ 12 // StationOne one =ne

微商直播卖货小程序

电商卖货直播系统开发咨询:陈经理180-2406-2897(微/电)电商直播开发/微信公众号直播/电商卖货直播小程序 如今,观看直播已经成为越来越多人的休闲选择.各类直播内容也一拥而出,"直播+"也成为了时下最热门的词."直播+电商"的模式也为卖家带来了更多买家的流量,在休闲的同时也获得了自己的所需. 来看看传统电商存在着那些缺点: 卖家直播卖货小程序系统 电商关于消费者来说最大的缺点是,经过互联网得到信息,只能经过图片和文字来区分产品的细节.颜色.运用作用等等,这

java 学习 ——文本编辑框小程序

简易的文本编辑框小程序: import java.awt.*; import java.awt.event.*; import javax.swing.*; import java.io.*; class TextEditorFrame extends JFrame{ File file=null; Color color=Color.red; TextEditorFrame(){ initTextPane(); initAboutDialog(); initToolBar(); initMen