黑马程序员技术交流社区

标题: 线程的随机怎么体现 [打印本页]

作者: 孙铭泽    时间: 2012-8-22 10:47
标题: 线程的随机怎么体现
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--) + "票");
                                }
                        }
                }
        }
}

我的同步代码块出的随机我分析不出来求解释。
作者: 吴小东    时间: 2012-8-22 11:01
tickets 要设置为静态,不然你每次开启线程的tickets 的数量都不是同一个tickets。
作者: 刘芮铭    时间: 2012-8-22 11:04
本帖最后由 刘芮铭 于 2012-8-22 11:07 编辑

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

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

作者: 李知伦    时间: 2012-8-22 11:13
线程本身就是随机的,即使你让它sleep
你多建几个线程就看出来了,每次运行的机会都不一样
线程之间会相互竞争,概率是随机的吧
锁竞争会导致的CPU饥饿现象,是引起多核CPU性能无法发挥的最重要原因之一
就是说cpu本来可算很快,但是线程有锁竞争轮流不了那么快




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2