java多線程模擬實現12306售票


業務描述

假設有200張票,用4個線程去訂票,不能有兩個或者以上的線程訂到了同一個票(原因就不說了),當最后一張票賣掉的時候結束,再訂就拋異常提示出票賣完了。

業務分析

要實現以上功能,1、需要創建一個車票類,初始化票,賣票的接口saleTicket()

2、自定義異常的一個類,這個很簡單,不多說。

3、創建賣票線程類,在run方法中賣車票。

4、初始化車票的線程,負責初始化車票,也就是初始化Ticket類中的數組。

5、創建主函數進行測試。

話不多說,上代碼。

package javasimple;

public class SaleTicket {

    public static void main(String[] args) {
        // 創建一個初始化線程,若干個買票線程
        // 要等初始化線程初始化好了之后,才能買票

        // 創建一個Ticket類的對象,分別傳給不同的線程
        Ticket ticket = new Ticket();

        Thread t1 = new InitTicketThread("初始化線程", ticket);

        // 等初始化線程初始化好車票之后,才能開始賣票
        try {
            t1.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        // 創建四個買票線程,開始賣票
        Thread t2 = new SaleTicketThread("賣票線程1", ticket);
        Thread t3 = new SaleTicketThread("賣票線程2", ticket);
        Thread t4 = new SaleTicketThread("賣票線程3", ticket);
        Thread t5 = new SaleTicketThread("賣票線程4", ticket);
    }
}
/**
 * 創建車票類、初始化車票
 * @author haokui
 *
 */
class Ticket {
    // 初始化200張票的空間
    private String[] tickets = new String[200];

    private int index = tickets.length - 1; // 指向數組的索引(第一張票)

    public Ticket() {

    }

    public void initTicket() {
        // 初始化車票,給數組的元素賦值,考慮是否要同步
        for (int i = 0; i < tickets.length; i++) {
            tickets[i] = "第" + (i + 1) + "號車票";
        }
    }

    public synchronized String saleTicket() throws NoTicketException {
        // 判斷是否有票,有票的情況下再賣票,沒有票呢,拋出異常,
        // 考慮是否需要同步

        if (index >= 0) {
            String s = tickets[index];
            
            // 故意制造了一個問題,出現多個線程共賣一張車票
            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            tickets[index] = null;
            index--;
            return s;
        } else {
            throw new NoTicketException("沒有車票了");
        }

    }
}
/**
 * 創建賣票線程類
 * @author haokui
 *
 */
class SaleTicketThread extends Thread {

    private Ticket ticket;

    public SaleTicketThread(String name, Ticket ticket) {
        super(name);
        this.ticket = ticket;
        this.start();
    }

    // 在run方法中賣車票
    public void run() {
        for (int i = 0; i < 60; i++) {
            try {
                String s = ticket.saleTicket();
                System.out.println(this.getName() + "賣票成功========>" + s);
            } catch (NoTicketException e) {
                System.out.println(this.getName() + " 賣票時發生異常!");
                e.printStackTrace();
                
                // 如果發生異常,說明沒有車票了,就中斷循環,不要在賣票了
                break;
            }
        }
    }
}
/**
 * 初始化車票的線程,負責初始化車票,也就是初始化Ticket類中的數組
 * @author haokui
 *
 */
 class InitTicketThread extends Thread {
    private Ticket ticket;
    public InitTicketThread(String name, Ticket ticket) {
        super(name);
        this.ticket = ticket;
        this.start();
    }

    // 在run方法中初始化車票
    public void run() {
        ticket.initTicket();
    }
}
 /**
  * 自定義異常
  * @author haokui
  *
  */
 class NoTicketException extends Exception {
        public NoTicketException() {

        }

        public NoTicketException(String msg) {
            super(msg);
        }
    }

以上代碼運行結果如下:

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM