業務描述
假設有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); } }
以上代碼運行結果如下: