• 使用java多线程模拟一个售票系统


    1.基于继承Thread实现

    代码实现:

    /**
     * 多线程模拟售票,基于Thread
     */
    public class TicketSalesByThread {
        public static void main(String[] args) {
            SellTicket sellTicket = new SellTicket();
            SellTicket sellTicket1 = new SellTicket();
            SellTicket sellTicket2 = new SellTicket();
            sellTicket.start();
            sellTicket1.start();
            sellTicket2.start();
        }
    }
    
    
    class SellTicket extends Thread {
        // 余票
        private static int ticketNum = 100;
        @Override
        public void run() {
            while (true) {
                if (ticketNum <= 0) {
                    System.out.println("没有余票!");
                    break;
                }
                // 休眠卖票
                try {
                    Thread.sleep(50);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
                System.out.println("窗口" + Thread.currentThread().getName() +
                        "售出一张票。" + "剩余票数:" + (--ticketNum));
            }
        }
    }
    
    • 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
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36

    结果分析:

    窗口Thread-1售出一张票。剩余票数:97
    窗口Thread-0售出一张票。剩余票数:98
    窗口Thread-2售出一张票。剩余票数:99
    窗口Thread-0售出一张票。剩余票数:96
    窗口Thread-1售出一张票。剩余票数:96
    窗口Thread-2售出一张票。剩余票数:95
    窗口Thread-0售出一张票。剩余票数:94
    窗口Thread-1售出一张票。剩余票数:93
    窗口Thread-2售出一张票。剩余票数:92
    窗口Thread-0售出一张票。剩余票数:91
    窗口Thread-1售出一张票。剩余票数:90
    窗口Thread-2售出一张票。剩余票数:89
    窗口Thread-0售出一张票。剩余票数:88
    窗口Thread-1售出一张票。剩余票数:87
    窗口Thread-2售出一张票。剩余票数:86
    窗口Thread-0售出一张票。剩余票数:85
    窗口Thread-1售出一张票。剩余票数:84
    窗口Thread-2售出一张票。剩余票数:83
    窗口Thread-0售出一张票。剩余票数:82
    窗口Thread-1售出一张票。剩余票数:81
    窗口Thread-2售出一张票。剩余票数:80
    窗口Thread-0售出一张票。剩余票数:79
    窗口Thread-1售出一张票。剩余票数:78
    窗口Thread-2售出一张票。剩余票数:77
    窗口Thread-0售出一张票。剩余票数:76
    窗口Thread-1售出一张票。剩余票数:75
    窗口Thread-2售出一张票。剩余票数:74
    窗口Thread-0售出一张票。剩余票数:73
    窗口Thread-1售出一张票。剩余票数:72
    窗口Thread-2售出一张票。剩余票数:71
    窗口Thread-0售出一张票。剩余票数:70
    窗口Thread-1售出一张票。剩余票数:69
    窗口Thread-2售出一张票。剩余票数:68
    窗口Thread-0售出一张票。剩余票数:67
    窗口Thread-1售出一张票。剩余票数:66
    窗口Thread-2售出一张票。剩余票数:65
    窗口Thread-0售出一张票。剩余票数:64
    窗口Thread-1售出一张票。剩余票数:63
    窗口Thread-2售出一张票。剩余票数:62
    窗口Thread-0售出一张票。剩余票数:61
    窗口Thread-1售出一张票。剩余票数:60
    窗口Thread-2售出一张票。剩余票数:59
    窗口Thread-0售出一张票。剩余票数:58
    窗口Thread-1售出一张票。剩余票数:57
    窗口Thread-2售出一张票。剩余票数:56
    窗口Thread-0售出一张票。剩余票数:55
    窗口Thread-1售出一张票。剩余票数:54
    窗口Thread-2售出一张票。剩余票数:53
    窗口Thread-0售出一张票。剩余票数:52
    窗口Thread-1售出一张票。剩余票数:51
    窗口Thread-2售出一张票。剩余票数:50
    窗口Thread-0售出一张票。剩余票数:49
    窗口Thread-1售出一张票。剩余票数:48
    窗口Thread-2售出一张票。剩余票数:47
    窗口Thread-0售出一张票。剩余票数:46
    窗口Thread-1售出一张票。剩余票数:45
    窗口Thread-2售出一张票。剩余票数:44
    窗口Thread-0售出一张票。剩余票数:43
    窗口Thread-1售出一张票。剩余票数:42
    窗口Thread-2售出一张票。剩余票数:41
    窗口Thread-0售出一张票。剩余票数:40
    窗口Thread-1售出一张票。剩余票数:39
    窗口Thread-2售出一张票。剩余票数:38
    窗口Thread-0售出一张票。剩余票数:37
    窗口Thread-1售出一张票。剩余票数:36
    窗口Thread-2售出一张票。剩余票数:35
    窗口Thread-0售出一张票。剩余票数:34
    窗口Thread-1售出一张票。剩余票数:33
    窗口Thread-2售出一张票。剩余票数:32
    窗口Thread-0售出一张票。剩余票数:31
    窗口Thread-1售出一张票。剩余票数:30
    窗口Thread-2售出一张票。剩余票数:29
    窗口Thread-0售出一张票。剩余票数:28
    窗口Thread-1售出一张票。剩余票数:27
    窗口Thread-2售出一张票。剩余票数:26
    窗口Thread-0售出一张票。剩余票数:25
    窗口Thread-1售出一张票。剩余票数:24
    窗口Thread-2售出一张票。剩余票数:23
    窗口Thread-0售出一张票。剩余票数:22
    窗口Thread-1售出一张票。剩余票数:21
    窗口Thread-2售出一张票。剩余票数:20
    窗口Thread-0售出一张票。剩余票数:19
    窗口Thread-1售出一张票。剩余票数:18
    窗口Thread-2售出一张票。剩余票数:17
    窗口Thread-0售出一张票。剩余票数:16
    窗口Thread-1售出一张票。剩余票数:15
    窗口Thread-2售出一张票。剩余票数:14
    窗口Thread-0售出一张票。剩余票数:13
    窗口Thread-1售出一张票。剩余票数:12
    窗口Thread-2售出一张票。剩余票数:11
    窗口Thread-0售出一张票。剩余票数:10
    窗口Thread-1售出一张票。剩余票数:9
    窗口Thread-2售出一张票。剩余票数:8
    窗口Thread-0售出一张票。剩余票数:7
    窗口Thread-1售出一张票。剩余票数:6
    窗口Thread-2售出一张票。剩余票数:5
    窗口Thread-0售出一张票。剩余票数:4
    窗口Thread-1售出一张票。剩余票数:3
    窗口Thread-2售出一张票。剩余票数:2
    窗口Thread-0售出一张票。剩余票数:1
    窗口Thread-1售出一张票。剩余票数:0
    没有余票!
    窗口Thread-2售出一张票。剩余票数:-1
    没有余票!
    窗口Thread-0售出一张票。剩余票数:-2
    没有余票!
    
    • 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
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106

    可以看到,基于Thread的实现,出现了明显的超卖现象!😶‍🌫️

    那么,为什么会发生这种情况呢?

    原因分析:

    当一个窗口还未执行--ticketNum操作时,另一个窗口已经进行售票状态,跳过了while循环的限制


    2.基于实现Runnable接口实现

    代码实现:

    /**
     * 多线程模拟售票,基于实现Runnable接口
     */
    public class TicketSalesByRunnable {
        public static void main(String[] args) {
            SellTicket02 sellTicket02 = new SellTicket02();
            new Thread(sellTicket02).start();
            new Thread(sellTicket02).start();
            new Thread(sellTicket02).start();
        }
    }
    
    class SellTicket02 implements Runnable {
        private int ticketNum = 100;
        @Override
        public void run() {
            while (true) {
                if (ticketNum <= 0) {
                    System.out.println("没有余票!");
                    break;
                }
                // 休眠卖票
                try {
                    Thread.sleep(50);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
                System.out.println("窗口" + Thread.currentThread().getName() +
                        "售出一张票。" + "剩余票数:" + (--ticketNum));
            }
        }
    }
    
    • 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
    • 31
    • 32

    结果分析:

    窗口Thread-0售出一张票。剩余票数:99
    窗口Thread-2售出一张票。剩余票数:98
    窗口Thread-1售出一张票。剩余票数:98
    窗口Thread-0售出一张票。剩余票数:97
    窗口Thread-2售出一张票。剩余票数:96
    窗口Thread-1售出一张票。剩余票数:95
    窗口Thread-0售出一张票。剩余票数:94
    窗口Thread-2售出一张票。剩余票数:94
    窗口Thread-1售出一张票。剩余票数:93
    窗口Thread-2售出一张票。剩余票数:92
    窗口Thread-0售出一张票。剩余票数:91
    窗口Thread-1售出一张票。剩余票数:90
    窗口Thread-2售出一张票。剩余票数:89
    窗口Thread-0售出一张票。剩余票数:88
    窗口Thread-1售出一张票。剩余票数:87
    窗口Thread-0售出一张票。剩余票数:86
    窗口Thread-2售出一张票。剩余票数:85
    窗口Thread-1售出一张票。剩余票数:84
    窗口Thread-2售出一张票。剩余票数:83
    窗口Thread-0售出一张票。剩余票数:83
    窗口Thread-1售出一张票。剩余票数:82
    窗口Thread-2售出一张票。剩余票数:80
    窗口Thread-0售出一张票。剩余票数:81
    窗口Thread-1售出一张票。剩余票数:79
    窗口Thread-2售出一张票。剩余票数:77
    窗口Thread-0售出一张票。剩余票数:78
    窗口Thread-1售出一张票。剩余票数:76
    窗口Thread-2售出一张票。剩余票数:75
    窗口Thread-0售出一张票。剩余票数:74
    窗口Thread-1售出一张票。剩余票数:73
    窗口Thread-2售出一张票。剩余票数:72
    窗口Thread-0售出一张票。剩余票数:71
    窗口Thread-1售出一张票。剩余票数:70
    窗口Thread-2售出一张票。剩余票数:69
    窗口Thread-0售出一张票。剩余票数:68
    窗口Thread-1售出一张票。剩余票数:67
    窗口Thread-2售出一张票。剩余票数:66
    窗口Thread-0售出一张票。剩余票数:65
    窗口Thread-1售出一张票。剩余票数:64
    窗口Thread-2售出一张票。剩余票数:63
    窗口Thread-0售出一张票。剩余票数:62
    窗口Thread-1售出一张票。剩余票数:61
    窗口Thread-2售出一张票。剩余票数:60
    窗口Thread-0售出一张票。剩余票数:59
    窗口Thread-1售出一张票。剩余票数:58
    窗口Thread-2售出一张票。剩余票数:57
    窗口Thread-0售出一张票。剩余票数:56
    窗口Thread-1售出一张票。剩余票数:55
    窗口Thread-2售出一张票。剩余票数:54
    窗口Thread-0售出一张票。剩余票数:53
    窗口Thread-1售出一张票。剩余票数:52
    窗口Thread-2售出一张票。剩余票数:51
    窗口Thread-0售出一张票。剩余票数:50
    窗口Thread-1售出一张票。剩余票数:49
    窗口Thread-2售出一张票。剩余票数:48
    窗口Thread-0售出一张票。剩余票数:47
    窗口Thread-1售出一张票。剩余票数:46
    窗口Thread-2售出一张票。剩余票数:45
    窗口Thread-0售出一张票。剩余票数:44
    窗口Thread-1售出一张票。剩余票数:43
    窗口Thread-2售出一张票。剩余票数:42
    窗口Thread-0售出一张票。剩余票数:41
    窗口Thread-1售出一张票。剩余票数:40
    窗口Thread-2售出一张票。剩余票数:39
    窗口Thread-0售出一张票。剩余票数:38
    窗口Thread-1售出一张票。剩余票数:37
    窗口Thread-2售出一张票。剩余票数:36
    窗口Thread-0售出一张票。剩余票数:35
    窗口Thread-1售出一张票。剩余票数:34
    窗口Thread-2售出一张票。剩余票数:33
    窗口Thread-0售出一张票。剩余票数:32
    窗口Thread-1售出一张票。剩余票数:31
    窗口Thread-2售出一张票。剩余票数:30
    窗口Thread-0售出一张票。剩余票数:29
    窗口Thread-1售出一张票。剩余票数:28
    窗口Thread-2售出一张票。剩余票数:27
    窗口Thread-0售出一张票。剩余票数:26
    窗口Thread-1售出一张票。剩余票数:25
    窗口Thread-2售出一张票。剩余票数:24
    窗口Thread-0售出一张票。剩余票数:23
    窗口Thread-1售出一张票。剩余票数:22
    窗口Thread-2售出一张票。剩余票数:21
    窗口Thread-0售出一张票。剩余票数:20
    窗口Thread-1售出一张票。剩余票数:19
    窗口Thread-2售出一张票。剩余票数:18
    窗口Thread-0售出一张票。剩余票数:17
    窗口Thread-1售出一张票。剩余票数:16
    窗口Thread-2售出一张票。剩余票数:15
    窗口Thread-0售出一张票。剩余票数:14
    窗口Thread-1售出一张票。剩余票数:13
    窗口Thread-2售出一张票。剩余票数:12
    窗口Thread-0售出一张票。剩余票数:11
    窗口Thread-1售出一张票。剩余票数:10
    窗口Thread-2售出一张票。剩余票数:9
    窗口Thread-0售出一张票。剩余票数:8
    窗口Thread-1售出一张票。剩余票数:7
    窗口Thread-2售出一张票。剩余票数:6
    窗口Thread-0售出一张票。剩余票数:5
    窗口Thread-1售出一张票。剩余票数:4
    窗口Thread-2售出一张票。剩余票数:3
    窗口Thread-0售出一张票。剩余票数:2
    窗口Thread-1售出一张票。剩余票数:1
    窗口Thread-2售出一张票。剩余票数:0
    没有余票!
    窗口Thread-0售出一张票。剩余票数:-1
    没有余票!
    窗口Thread-1售出一张票。剩余票数:-2
    没有余票!
    
    • 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
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108

    仍然会有超卖现象发生!


    3.通知线程退出

    有时候,我们需要不同的线程可以相互控制对方的运行

    可以采用通知线程中止来解决此类问题,比如我们简单实现一个DEMO,实现主线程通知中止其他线程的效果:

    /**
     * 通知线程中止
     */
    public class ThreadExit {
        public static void main(String[] args) throws InterruptedException {
            TTT ttt = new TTT();
            ttt.start();
            Thread.sleep(5000);
            // 主线程通知其他线程退出
            ttt.setLoop(false);
        }
    }
    
    class TTT extends Thread {
        // 控制变量
        private boolean loop = true;
        @Override
        public void run() {
            while (loop) {
                try {
                    Thread.sleep(50);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
                System.out.println("TTT线程正在运行...");
            }
        }
    
        public void setLoop(boolean loop) {
            this.loop = loop;
        }
    }
    
    • 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
    • 31
    • 32

    TTT线程会运行5秒,随后由主线程通知退出🤖


    4.解决超卖问题,线程同步机制

    在多线程编程中,一些敏感数据不允许被多个线程同时访问,此时就可以使用同步访问技术,保证数据在同一时刻只能有一个线程访问,以保证数据的完整性

    synchronized线程同步:即当有一个线程在对内存进行操作时,其他线程都不可以对这个内存地址进行操作,直到该线程完成操作🤖

    上成品代码:

    /**
     * 使用同步机制解决售票问题的超卖现象
     */
    public class TicketSalesResult {
        public static void main(String[] args) {
            SellTicketRes sellTicketRes = new SellTicketRes();
            new Thread(sellTicketRes).start();
            new Thread(sellTicketRes).start();
            new Thread(sellTicketRes).start();
        }
    }
    
    class SellTicketRes implements Runnable {
        private int ticketNum = 100;
        private boolean loop = true;
    
        /**
         * 使用synchronized实现线程同步,解决超卖
         */
        public synchronized void Sell() {
            if (ticketNum <= 0) {
                System.out.println("没有余票!");
                loop = false;
                return;
            }
            // 休眠卖票
            try {
                Thread.sleep(50);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            System.out.println("窗口" + Thread.currentThread().getName() +
                    "售出一张票。" + "剩余票数:" + (--ticketNum));
        }
        @Override
         public void run() {
            while (true) {
                if (loop == false) {
                    break;
                }
                Sell();
            }
        }
    }
    
    • 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
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44

    结果分析:(完美解决超卖问题)

    窗口Thread-0售出一张票。剩余票数:99
    窗口Thread-0售出一张票。剩余票数:98
    窗口Thread-0售出一张票。剩余票数:97
    窗口Thread-0售出一张票。剩余票数:96
    窗口Thread-0售出一张票。剩余票数:95
    窗口Thread-0售出一张票。剩余票数:94
    窗口Thread-0售出一张票。剩余票数:93
    窗口Thread-0售出一张票。剩余票数:92
    窗口Thread-0售出一张票。剩余票数:91
    窗口Thread-0售出一张票。剩余票数:90
    窗口Thread-0售出一张票。剩余票数:89
    窗口Thread-0售出一张票。剩余票数:88
    窗口Thread-0售出一张票。剩余票数:87
    窗口Thread-0售出一张票。剩余票数:86
    窗口Thread-0售出一张票。剩余票数:85
    窗口Thread-0售出一张票。剩余票数:84
    窗口Thread-0售出一张票。剩余票数:83
    窗口Thread-0售出一张票。剩余票数:82
    窗口Thread-0售出一张票。剩余票数:81
    窗口Thread-0售出一张票。剩余票数:80
    窗口Thread-2售出一张票。剩余票数:79
    窗口Thread-2售出一张票。剩余票数:78
    窗口Thread-2售出一张票。剩余票数:77
    窗口Thread-2售出一张票。剩余票数:76
    窗口Thread-2售出一张票。剩余票数:75
    窗口Thread-2售出一张票。剩余票数:74
    窗口Thread-2售出一张票。剩余票数:73
    窗口Thread-2售出一张票。剩余票数:72
    窗口Thread-2售出一张票。剩余票数:71
    窗口Thread-1售出一张票。剩余票数:70
    窗口Thread-1售出一张票。剩余票数:69
    窗口Thread-1售出一张票。剩余票数:68
    窗口Thread-1售出一张票。剩余票数:67
    窗口Thread-1售出一张票。剩余票数:66
    窗口Thread-1售出一张票。剩余票数:65
    窗口Thread-1售出一张票。剩余票数:64
    窗口Thread-1售出一张票。剩余票数:63
    窗口Thread-1售出一张票。剩余票数:62
    窗口Thread-1售出一张票。剩余票数:61
    窗口Thread-1售出一张票。剩余票数:60
    窗口Thread-1售出一张票。剩余票数:59
    窗口Thread-1售出一张票。剩余票数:58
    窗口Thread-1售出一张票。剩余票数:57
    窗口Thread-1售出一张票。剩余票数:56
    窗口Thread-1售出一张票。剩余票数:55
    窗口Thread-1售出一张票。剩余票数:54
    窗口Thread-1售出一张票。剩余票数:53
    窗口Thread-1售出一张票。剩余票数:52
    窗口Thread-1售出一张票。剩余票数:51
    窗口Thread-1售出一张票。剩余票数:50
    窗口Thread-1售出一张票。剩余票数:49
    窗口Thread-1售出一张票。剩余票数:48
    窗口Thread-1售出一张票。剩余票数:47
    窗口Thread-1售出一张票。剩余票数:46
    窗口Thread-1售出一张票。剩余票数:45
    窗口Thread-1售出一张票。剩余票数:44
    窗口Thread-1售出一张票。剩余票数:43
    窗口Thread-1售出一张票。剩余票数:42
    窗口Thread-2售出一张票。剩余票数:41
    窗口Thread-2售出一张票。剩余票数:40
    窗口Thread-2售出一张票。剩余票数:39
    窗口Thread-2售出一张票。剩余票数:38
    窗口Thread-2售出一张票。剩余票数:37
    窗口Thread-2售出一张票。剩余票数:36
    窗口Thread-2售出一张票。剩余票数:35
    窗口Thread-2售出一张票。剩余票数:34
    窗口Thread-2售出一张票。剩余票数:33
    窗口Thread-2售出一张票。剩余票数:32
    窗口Thread-2售出一张票。剩余票数:31
    窗口Thread-2售出一张票。剩余票数:30
    窗口Thread-2售出一张票。剩余票数:29
    窗口Thread-2售出一张票。剩余票数:28
    窗口Thread-2售出一张票。剩余票数:27
    窗口Thread-2售出一张票。剩余票数:26
    窗口Thread-2售出一张票。剩余票数:25
    窗口Thread-2售出一张票。剩余票数:24
    窗口Thread-2售出一张票。剩余票数:23
    窗口Thread-2售出一张票。剩余票数:22
    窗口Thread-2售出一张票。剩余票数:21
    窗口Thread-2售出一张票。剩余票数:20
    窗口Thread-2售出一张票。剩余票数:19
    窗口Thread-2售出一张票。剩余票数:18
    窗口Thread-2售出一张票。剩余票数:17
    窗口Thread-2售出一张票。剩余票数:16
    窗口Thread-0售出一张票。剩余票数:15
    窗口Thread-0售出一张票。剩余票数:14
    窗口Thread-0售出一张票。剩余票数:13
    窗口Thread-0售出一张票。剩余票数:12
    窗口Thread-0售出一张票。剩余票数:11
    窗口Thread-0售出一张票。剩余票数:10
    窗口Thread-0售出一张票。剩余票数:9
    窗口Thread-0售出一张票。剩余票数:8
    窗口Thread-0售出一张票。剩余票数:7
    窗口Thread-2售出一张票。剩余票数:6
    窗口Thread-2售出一张票。剩余票数:5
    窗口Thread-2售出一张票。剩余票数:4
    窗口Thread-2售出一张票。剩余票数:3
    窗口Thread-2售出一张票。剩余票数:2
    窗口Thread-2售出一张票。剩余票数:1
    窗口Thread-2售出一张票。剩余票数:0
    没有余票!
    没有余票!
    没有余票!
    
    • 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
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
  • 相关阅读:
    RESTful API 设计指南——开篇词
    Firebird + FireDAC 界面操作的自增字段
    【C++】C++11——可变参数模板和emplace
    Time Series Data Augmentation for Deep Learning: A Survey 之论文阅读
    LuatOS-SOC接口文档(air780E)-- fastlz - FastLZ压缩
    零经验,小白变大厨!
    salesforce零基础学习(一百一十三)Trigger中获取IP地址的过程
    实现深拷贝
    最详细的mysql安装教程+mysql文件下载链接
    webpack原理篇(五十六):webpack流程:模块构建和chunk生成阶段
  • 原文地址:https://blog.csdn.net/Gherbirthday0916/article/details/126083789