1. 程式人生 > >多個線程之間共享數據,(探究)一下十一的車票是怎麽賣的

多個線程之間共享數據,(探究)一下十一的車票是怎麽賣的

地方 water private ron image 關鍵字 ket css col

十月一到了,大家有沒有搶到回家的車票。筆者有事退了回家的臥鋪票,今年十一就不回家了。算下來有8個多月沒有回家了,混沌之余想想搶票是怎麽回事吧。為什麽會有許多的搶票軟件,還有12306發售的,還有售票窗口發售的。就不會賣重嗎?
題設來了:現在剩下1000張票了,有的地方在買票、有的還像筆者一樣退了票。其實歸根結底,我們操作的都是12306的共享數據那1000張票。
在這裏不得不講解一下,一個關鍵的地方:

synchronized 關鍵字,代表這個方法加鎖

也就是說當線程運行到這個方法的時候,就開始檢查有沒有其他線程正在使用這個方法,有的話就等待其他線程運行完畢,沒有的話就自己運行(好像很紳士的樣子,你先上,你請,最後在自己上)。筆者在想,當我看到有票慌忙填數據提交完買票之後,瀏覽器開始刷新,刷了一小會之後告訴我“票已經賣空了”,應該就是synchronized的鍋吧。

synchronized關鍵字最主要有以下3種應用方式

    修飾實例方法,作用於當前實例加鎖,進入同步代碼前要獲得當前實例的鎖
    修飾靜態方法,作用於當前類對象加鎖,進入同步代碼前要獲得當前類對象的鎖
    修飾代碼塊,指定加鎖對象,對給定對象加鎖,進入同步代碼庫前要獲得給定對象的鎖。

     這裏只是一個簡單的售票原理。真實情況肯定不會這麽的簡單,但簡單又可以羅列出復雜。

貼出簡單原理:

    package com.css.java.learning.ticket;
    /**
     * 探究火車票的售賣原理
     * @author Red_Ant
     * 20180928
     */
    public class SaleTrainTicket {
        private int totalCount = 1000;//通過什麽途徑獲得的數據,筆者不管。反正就1000張票。
        //賣票
        public synchronized int SaleTicket(int num) {
            totalCount = totalCount - num;
            return totalCount;
        }
        //退票
        public synchronized int RebackTicket(int num) {
            if(totalCount < 0) {
                totalCount = 0;
            }
            totalCount = totalCount + num;
            return totalCount;
        }
    }

接下來就是各個售票部分的調用,有的賣票,有的辦理退票。簡單的調用代碼:

SaleTrainTicket manager = new SaleTrainTicket();
        new Thread(new Runnable() {
            @Override
            public void run() {
                int leaveNum = manager.SaleTicket(2);
                if(leaveNum <= 0) {
                    System.err.println("呵呵,已經沒票了");;
                }else {
                    System.err.println("還有" + leaveNum + "張票");
                }
            }
        }).start();

        new Thread(new Runnable() {
            @Override
            public void run() {
                int num = manager.RebackTicket(1);
                System.err.println("退票之後,還有" + num + "張");
            }
        }).start();

    }

【後話】
像數據共享這塊,肯定不是筆者這樣的簡單操作。得是共享數據庫數據吧!
我想原理差不多就這樣吧。

運行的一個小效果:

技術分享圖片

多個線程之間共享數據,(探究)一下十一的車票是怎麽賣的