Java简单的多线程卖票

package xiancheng;
/*
 定义一个MaiPiao类实现Runnable接口,里面定义一个成员变量: private int tickets =100(票数);
 在类中重写run()方法实现卖票,代码步骤如下
 1:判断票数大于0,就卖票,并告知是哪个窗口卖的
 2:卖了票之后,总票数要减1
 3:票没有了,也可能有人来问,所以这里用死循环让卖票的动作一直执行
 定义一个测试类MaiPiaoDemo,里面有main方法,代码步骤如下
 1:创建MaiPiao类的对象
 2:创建三个Thread类的对象,把MaiPiao对象作为构造方法的参数,并给出对应的窗口名称
 3:启动线程
 */
public class MaiPiaoDome {
	public static void main(String[] args) {
		//创建MaiPiao类的对象
		MaiPiao m=new MaiPiao();

		//创建三个Thread类的对象,把MaiPiao对象作为构造方法的参数,并给出对应的窗口名称
		Thread t1=new Thread(m,"售票口1");
		Thread t2=new Thread(m,"售票口2");
		Thread t3=new Thread(m,"售票口3");
		//启动线程
		t1.start();
		t2.start();
		t3.start();
	}
}
package xiancheng;

public class MaiPiao implements Runnable {
	private int tickets =100;
	public void run() {
		while(true) {
			if(tickets>0) {
				try {
					Thread.sleep(100);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				System.out.println(Thread.currentThread().getName()+"正在出售第"+tickets+"张票");
				tickets--;
			}
		}
	}
}

同步代码块学习记录:

在MaiPiao类中添加了sleep()方法后

出现了问题 如出现卖的票数为-1或者同个窗口卖出一样的票

为什么出现问题?(这也是我们判断多线程程序是否会有数据安全问题的标准)

1、是否是多线程环境

2、是否有共享数据

3、是否有多条语句操作共享数据

如何解决多线程安全问题呢?

基本思想:让程序没有安全问题的环境

怎么实现呢?

把多条语句操作共享数据的代码给锁起来,让任意时刻只能有一个线程执行即可Java提供了同步代码块的方式来解决

锁多条语句操作共享数据,可以使用同步代码块实现

格式:

synchronized(任意对象){

多条语句操作共享数据的代码

}

synchronized(任意对象):就相当于给代码加锁了,任意对象就可以看成是一把锁

使用同步代码块后的MaiPiao类:

package xiancheng;

public class MaiPiao implements Runnable {
	private int tickets =100;
	private Object obj =new Object();
	public void run() {
		while(true) {
			synchronized(obj) {
			if(tickets>0) {
				try {
					Thread.sleep(100);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				System.out.println(Thread.currentThread().getName()+"正在出售第"+tickets+"张票");
				tickets--;
			}
		}
		}
	}
}

同步方法学习记录:

package xiancheng;
/*
   	同步方法:就是把synchronized关键字加到方法上
	格式:
	修饰符synchronized返回值类型 方法名(方法参数){}
	同步方法的锁对象是什么呢?
	this
	同步静态方法:就是把synchronized关键字加到静态方法上
	格式:
	修饰符static synchronized返回值类型 方法名(方法参数){}
	同步静态方法的锁对象是什么呢?
	类名.class
 */
public class MaiPiao implements Runnable {
	//private int tickets =100;
	private static int tickets =100;
	private Object obj =new Object();
	private int x=0;
	public void run() {
		while(true) {
			if(x%2==0) {
			//synchronized(obj) {
			//同步方法的锁对象是什么呢?   this		
//			synchronized(this) {
//			同步静态方法的锁对象是什么呢?
//			类名.class
			synchronized(MaiPiao.class) {
			if(tickets>0) {
				try {
					Thread.sleep(100);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				System.out.println(Thread.currentThread().getName()+"正在出售第"+tickets+"张票");
				tickets--;
			}
		}
		}
		else {
//			synchronized(obj) {
//				if(tickets>0) {
//					try {
//						Thread.sleep(100);
//					} catch (InterruptedException e) {
//						// TODO Auto-generated catch block
//						e.printStackTrace();
//					}
//					System.out.println(Thread.currentThread().getName()+"正在出售第"+tickets+"张票");
//					tickets--;
//				}
//			}
			s();
		}
			x++;
	}
	}
	//同步方法:就是把synchronized关键字加到方法上
//	格式:
//	修饰符synchronized返回值类型 方法名(方法参数){}
//	public synchronized void s() {
//			if(tickets>0) {
//				try {
//					Thread.sleep(100);
//				} catch (InterruptedException e) {
//					// TODO Auto-generated catch block
//					e.printStackTrace();
//				}
//				System.out.println(Thread.currentThread().getName()+"正在出售第"+tickets+"张票");
//				tickets--;
//			}
//	}
//	同步静态方法:就是把synchronized关键字加到静态方法上
//	格式:
//	修饰符static synchronized返回值类型 方法名(方法参数){}
	public static synchronized void s() {
		if(tickets>0) {
			try {
				Thread.sleep(100);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			System.out.println(Thread.currentThread().getName()+"正在出售第"+tickets+"张票");
			tickets--;
		}
}
}

  • 1
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值