JAVA 多线程 模拟多窗口售票

Amber61 2016-09-19 05:35:22
package com.supinfo.java;
class Window1 implements Runnable{
int tickets = 300;
@Override
public void run() {
while(true){
if(tickets>0){
try {
Thread.currentThread().sleep(10);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+",售票,票号为:"+tickets--);
}else{
break;
}
}
}

}
public class TestWindow2 {
public static void main(String[] args) {
Window1 w1 = new Window1();
Thread t1 = new Thread(w1);
t1.setName("窗口1");
Thread t2 = new Thread(w1);
t2.setName("窗口2");
Thread t3 = new Thread(w1);
t3.setName("窗口3");

t1.start();
t2.start();
t3.start();


}
}

结果会有重票和错票,错票比较好理解,哪位大神给我解释下,为什么有重票的情况发生。
...全文
1833 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
逸花城 2016-10-23
  • 打赏
  • 举报
回复
先是if(ticket>0),休眠10毫秒后就不见得>0了,被其他线程减了。
晴天_ccc 2016-10-23
  • 打赏
  • 举报
回复
你的 int tickets = 300;是每一个window1对象中的非静态成员,也就是说,你new了多个window1的对象,每个对象中都有一个独立的tickets,所以不存在共享资源的概念 ,也谈不上存在线程安全问题。说白了,你就启动了3个线程,每个线程内部都是通过循环输入其内部的tickets变量而已,重票是肯定的。6楼已经给出了例子。
qq_34494077 2016-10-22
  • 打赏
  • 举报
回复
6楼已经写的很详细了 线程安全问题 要用锁 来解决
tomorrow_C 2016-10-11
  • 打赏
  • 举报
回复
你这是典型的线程安全问题,线程安全问题一般会用锁来解决,锁的作用是,一个线程执行所内部的程序时,其他线程是执行不了锁内部的代码的,楼上写的代码就是用了锁来解决线程安全问题
x业精于勤x 2016-10-10
  • 打赏
  • 举报
回复

/**
 * @Description 
 * 设计一个多线程程序如下:
 * 设计一个火车售票模拟程序。 假如火车站要有100张火车票要卖出,
 * 现在有5个售票点同时售票,用5个线程模拟这5个售票点的售票情况
 *	1、要求打印出每个售票点所卖出的票号
 *	2、各售票点不能售出相同票号的火车票
 * @author XPY
 * @date 2016年7月4日下午5:40:40
 */
public class ThreadTest3 {
	public static void main(String[] args) {
		Shop shop = new Shop();
		for (int i = 1; i <= 5; i++) {
			new Thread(shop,"").start();
		}
	}
}

class Shop implements Runnable{
	String name;
	ticket t;
	
	public Shop() {
		t.total = 100;
		t.count = 0;
		}

	public void run() {
		while (t.total>0) {
			synchronized (this) {
				try {
					Thread.sleep(new Random().nextInt(1000));
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				System.out.println(Thread.currentThread().getName()+"_____"+t.count);
				t.total--;
				t.count++;
			}	
		}

	}
}

class ticket {
	int total;
	int count;
}
我写的一个小例子 ,你可以看看就知道为什么了
qq_22002307 2016-09-19
  • 打赏
  • 举报
回复
你的总票数是分配在主存上的,而每个线程创建都会有自己的高速缓冲。线程要把主存上的数据弄到高速缓冲中,计算然后再把结果返回给主存,刷新总票数。这时候几个线程是对于总票数相互之间不可见的,就会造成多线程的问题。可以加锁,或者在总票数加 volatile试试,关于并发编程可以看看这个http://www.cnblogs.com/dolphin0520/p/3920373.html
e824595097 2016-09-19
  • 打赏
  • 举报
回复
如果一个线程在执行一个语句,比如说1234,但是刚执行到12, 34还没执行,cpu就被抢走了,就导致了出现安全问题,你加个锁就能解决这个问题了,细节自己百度synchronized,因为我也是个学生,不太了解
Amber61 2016-09-19
  • 打赏
  • 举报
回复
cpu资源不是线程之间来回切换的吗?怎么可以同时访问ticket呢?
soton_dolphin 2016-09-19
  • 打赏
  • 举报
回复
AtomicInteger ticket = new AtomicInteger(300)
soton_dolphin 2016-09-19
  • 打赏
  • 举报
回复
因为两个或三个线程可以同时更新ticket变量

62,628

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧