A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 李志广 中级黑马   /  2012-8-8 00:09  /  1772 人查看  /  5 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 李志广 于 2012-8-8 00:49 编辑

class Ticket implements Runnable
{
        private int ticket=100;
        public void run()
                {
                        while(true)
                                {
                                        if(ticket>0)
                                                {
                                                System.out.println(Thread.currentThread().getName()+"ticket:"+ticket--);
                                                }
                                }
                }
}
class  TicketDemo2
{
        public static void main(String[] args)
        {
                Ticket t=new Ticket();
                new Thread(t).start();
                new Thread(t).start();
                new Thread(t).start();
                new Thread(t).start();
        }
}
在毕老师讲解多线程买票时,在运用继承Thread类和实现Runnable接口做为比较,但是有一些问题还是不是太明白。
为什么实现Runnable接口时,ticket就变成了共享数据呢?还有在判断循环条件时为什么一定要加上while语句作为条件呢?
在本例中将while去掉,为什么不能打印出正确的结果?去掉while语句,if条件不也可以作为循环条件的判断吗?

评分

参与人数 1技术分 +1 收起 理由
杨志 + 1

查看全部评分

5 个回复

倒序浏览
为什么实现Runnable接口时,ticket就变成了共享数据呢?
ticket就变成了共享数据是因为你只创建了一个Ticket类型的对象 t,然后用同一个t又分别创建了4个线程对象,那么这4个线程用的都是t中ticket变量了。假如你创建4个Ticket类型对象t1、t2、t3、t4然后再用着4个Ticket类型的对象分别创建线程的话:
                new Thread(t1).start(); //这个线程拥有t1的ticket变量
                new Thread(t2).start(); //这个线程拥有t2的ticket变量
                new Thread(t3).start(); //这个线程拥有t3的ticket变量
                new Thread(t4).start(); //这个线程拥有t4的ticket变量
我保证这时的ticket就不是共享数据了。而是每个线程对象拥有一个ticket。

还有在判断循环条件时为什么一定要加上while语句作为条件呢?
加上while是为了让这个创建出来的线程能够一直运行run方法。假如你把while循环去掉的话,那么你创建出的4个线程在执行完run方法里面的if语句之后打印4条语句就结束了。也就是说每个线程只卖出一张票就结束了,这显然是不合理的。

在本例中将while去掉,为什么不能打印出正确的结果?
去掉while语句的话,线程在执行run方法时,只要一执行完if语句块,这个线程就结束了。程序运行的结果是每个线程打印一条语句。
去掉while语句,if条件不也可以作为循环条件的判断吗?
去掉while语句,if条件当然可以作为循环条件的判断。但是必须保证能够循环执行ticket变量减1的动作(也即票数减1的动作).比如可以这样写:
while(ticket>0)
{
                         System.out.println(Thread.currentThread().getName()+"ticket:"+ticket--);
}

评分

参与人数 1技术分 +1 收起 理由
田建 + 1 赞一个,加油!

查看全部评分

回复 使用道具 举报
只创建了一个Ticket对象,4个线程一起操作这一个对象,成员变量当然变成了共享数据了。
这里要打印100张票,当然要循环了,去掉while后,if条件只是一个判断语句,所以只会4个线程每个调用一次run()就会结束程序。
回复 使用道具 举报
呵呵,问题已解决!!!{:soso_e100:}
回复 使用道具 举报
牛杨 发表于 2012-8-8 02:34
为什么实现Runnable接口时,ticket就变成了共享数据呢?
ticket就变成了共享数据是因为你只创建了一个Tick ...

谢谢,解答的很明确
回复 使用道具 举报
李志广 发表于 2012-8-8 08:25
谢谢,解答的很明确

为什么没有给分呢?
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马