黑马程序员技术交流社区
标题:
多线程安全问题,标题一定要长--------------------------------
[打印本页]
作者:
徐传任
时间:
2012-10-10 12:59
标题:
多线程安全问题,标题一定要长--------------------------------
public class TicketDemo {
public static void main(String[] args) {
Ticket t = new Ticket();
Thread t0 = new Thread(t);
Thread t1 = new Thread(t);
t0.setName("窗口一:");
t1.setName("窗口二:");
t0.start();
t1.start();
}
}
class Ticket implements Runnable {
private int num = 100;
public void run() {
while(true) {
try {
sell();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public void sell() throws InterruptedException {
if(num>0) {
Thread.sleep(10);
System.out.println(Thread.currentThread().getName()+"卖票啦,卖票啦"+num--);
}
}
}
复制代码
我知道会产生安全问题,会出现0号票,不安全。但是我在运行的时候突然发现有两个同号的票,这个问题是怎么产生的。
窗口一卖票啦,卖票啦80
窗口二卖票啦,卖票啦80
窗口二卖票啦,卖票啦79
窗口一卖票啦,卖票啦78
窗口二卖票啦,卖票啦77
窗口一卖票啦,卖票啦76
窗口一卖票啦,卖票啦75
为什么会出现两个80号票呢?
是 num--在运行后给num赋值期间出现的问题吗?
如果分开写
System.out.println(Thread.currentThread().getName()+"卖票啦,卖票啦"+num);
num--;这样我知道是两条语句出现问题,
但是System.out.println(Thread.currentThread().getName()+"卖票啦,卖票啦"+num--);这不是一条语句吗为什么还会出现问题。
具体System.out.println(Thread.currentThread().getName()+"卖票啦,卖票啦"+num--);这条语句在多线程期间是怎么出现同号票安全问题的原因的,麻烦给解释下
作者:
王震阳老师
时间:
2012-10-10 13:08
你的程序没有加线程同步呀,有时候可能看不到问题,但有时候会出问题。加上线程同步就可以了。、
作者:
徐传任
时间:
2012-10-10 13:08
弄不大明白这个打印线程+num--,在内存中到底是具体怎么执行的
作者:
王震阳老师
时间:
2012-10-10 13:17
本帖最后由 王震阳 于 2012-10-10 13:28 编辑
public class TicketDemo {
public static void main(String[] args) {
Ticket t = new Ticket();
Thread t0 = new Thread(t);
Thread t1 = new Thread(t);
t0.setName("窗口一11111111111111:");
t1.setName("窗口二222:");
t0.start();
t1.start();
}
}
class Ticket implements Runnable {
private int num = 1000;//为了测试效果,将票数改为1000张
Object obj=new Object();//定义一个object对象
public void run() {
while(true) {
synchronized(obj)//在这个地方加了一个同步锁
{
try {
sell();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public void sell() throws InterruptedException {
if(num>0) {
Thread.sleep(10);
System.out.println(Thread.currentThread().getName()+"卖票啦,卖票啦"+num--);
}
}
}
运行截图:
复制代码
作者:
徐传任
时间:
2012-10-10 13:17
王震阳 发表于 2012-10-10 13:08
你的程序没有加线程同步呀,有时候可能看不到问题,但有时候会出问题。加上线程同步就可以了。、
...
我知道可能出现问题,但是分析不出来为什么会出现同一张票的问题,郁闷
作者:
王震阳老师
时间:
2012-10-10 13:26
本帖最后由 王震阳 于 2012-10-10 13:32 编辑
[quote]
徐传任 发表于 2012-10-10 13:17
http://edu.csdn.net/main/feature/bxd_25.shtml
你把第十一天的下载下来就知道了。
你的问题的主要解释为:因为cpu的执行不是连续的,每个线程都分配了执行时间,交换进行的,当第一个进程判断为true是,可能cpu就改换另一个进程了,
导致线程而也判断为true,这样两个线程都出售了同一张票。因此我们要解决这个方法就是,当线程1进入判断是,我们加一个锁,当线程1出来时再解锁,这样会降低系统运行的效率,
但是提高了安全性,或者说,类似于售票的问题,必须有线程安全方面的考虑。
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/)
黑马程序员IT技术论坛 X3.2