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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

public class SellTicket implements Runnable {
    // 定义100张票
    private int ticket = 100;

    public void run() {

        //假设一直在售票
        while(true){
        //现实中买票时,都会有延迟的,所以让线程休息下
        try {
            Thread.sleep(100);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        if(ticket > 0){
            System.out.println(Thread.currentThread().getName()+"正在出售第"+(ticket--)+"张票");
        }
        19         }
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public class SellTicket1Demo {

    public static void main(String[] args) {

        // 创建资源对象
        SellTicket st = new SellTicket();

        // 创建三个线程对象
        Thread st1 = new Thread(st,"售票口1");
        Thread st2 = new Thread(st,"售票口2");
        Thread st3 = new Thread(st,"售票口3");

        // 启动线程
        st1.start();
        st2.start();
        st3.start();

    }

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
当启动程序后,就会发现出现了2个问题:

问题1 相同的票卖了多次
CPU的一次操作必须是原子性的
原子性:最简单基本的操作,比如说i=100,System.out.println(i); 这个就是最简单基本的操作,不能拆分的,而i–就不是了。
出现了负数票
随机性和延迟导致的
问题1分析

//        @Override
//        public void run() {
//                while (true) {
//                        // t1,t2,t3三个线程
//                        // 这一次的tickets = 100;
//                        if (tickets > 0) {
//                                // 为了模拟更真实的场景,我们稍作休息
//                                try {
//                                        Thread.sleep(100); // t1就稍作休息,t2就稍作休息
//                                } catch (InterruptedException e) {
//                                        e.printStackTrace();
//                                }
//
//                                System.out.println(Thread.currentThread().getName() + "正在出售第"
//                                                + (tickets--) + "张票");
//                                // 理想状态:
//                                // 窗口1正在出售第100张票
//                                // 窗口2正在出售第99张票
//                                // 但是呢?
//                                // CPU的每一次执行必须是一个原子性(最简单基本的)的操作。
//                                // 先记录以前的值
//                                // 接着把ticket--
//                                // 然后输出以前的值(t2来了)
//                                // ticket的值就变成了99
//                                // 窗口1正在出售第100张票
//                                // 窗口2正在出售第100张票
//
//                        }
//                }
//        }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
问题2分析

        @Override
        public void run() {
                while (true) {
                        // t1,t2,t3三个线程
                        // 这一次的tickets = 1;
                        if (tickets > 0) {
                                // 为了模拟更真实的场景,我们稍作休息
                                try {
                                        Thread.sleep(100); //t1进来了并休息,t2进来了并休息,t3进来了并休息,
                                } catch (InterruptedException e) {
                                        e.printStackTrace();
                                }

                                System.out.println(Thread.currentThread().getName() + "正在出售第"
                                                + (tickets--) + "张票");
                                //窗口1正在出售第1张票,tickets=0
                                //窗口2正在出售第0张票,tickets=-1
                                //窗口3正在出售第-1张票,tickets=-2
                        }
                }
        }
---------------------
【转载,仅作分享,侵删】
作者:imxlw00
原文:https://blog.csdn.net/imxlw00/article/details/85331791


1 个回复

倒序浏览
奈斯
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马