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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 孙铭泽 中级黑马   /  2012-8-22 10:47  /  1464 人查看  /  3 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

public class TicketDemo4 implements Runnable {

        private int tickets = 100;

        Object obj = new Object();
       
        Demo d = new Demo();

        @Override
        public void run() {
                //Demo d = new Demo();
                while (true) {
                         
                        synchronized (d) {
                                if (tickets > 0) {
                                        try {
                                                Thread.sleep(10);
                                        } catch (InterruptedException e) {
                                                e.printStackTrace();
                                        }
                                        System.out.println(Thread.currentThread().getName() + "卖出第"
                                                        + (tickets--) + "票");
                                }
                        }
                }
        }
}

我的同步代码块出的随机我分析不出来求解释。

评分

参与人数 1技术分 +1 收起 理由
张_涛 + 1 赞一个!

查看全部评分

3 个回复

倒序浏览
tickets 要设置为静态,不然你每次开启线程的tickets 的数量都不是同一个tickets。
回复 使用道具 举报
本帖最后由 刘芮铭 于 2012-8-22 11:07 编辑

分析你的程序:首先你应该将tickes设置为静态的,这样数据才会共享!就相当于你每次试用的都是同一个数据,不然每次使用的都是新的tickes

流程看上去没有任何问题。但一旦将这个流程放在多线程并发的场景下,就有可能出现问题,但不是说一定。也许程序运行一百万次都没有出现问题,没有出现问题并不等于没有问题!这就是多线程访问同一数据的时候,数据安全性问题,在Java中主要有三种方法解决线程安全问题:同步代码块,同步方法,同步锁。
注意:系统的线程调度具有一定的随机性,比如你有5个线程,你可以通过结果的打印看出,每个线程出现的频率和次数是均不相同的!从而可以看出系统调用线程的随机性!
而想要看出线程的不安全性,不仅仅是需要将Tread.sleep(10)这么简单,线程的不安全是体现在:多线程,多基数等并发场景下产生的!

评分

参与人数 1技术分 +1 收起 理由
张_涛 + 1

查看全部评分

回复 使用道具 举报
线程本身就是随机的,即使你让它sleep
你多建几个线程就看出来了,每次运行的机会都不一样
线程之间会相互竞争,概率是随机的吧
锁竞争会导致的CPU饥饿现象,是引起多核CPU性能无法发挥的最重要原因之一
就是说cpu本来可算很快,但是线程有锁竞争轮流不了那么快
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马