訂票系統差很少是咱們最熟悉的一個關於線程併發的問題,如何作到多個售票窗口同時售票而不會致使將同一張票賣給多個旅客,首先很直觀 的一點就是當咱們把售票餘量的增減弄成一個事務,如此一來在增減票餘量的代碼執行的時候只能容許一個線程操做也就是出票只能是總部出票,那麼一個簡易的模型就出來了。java
首先全部車票(虛擬票使用票號代替)都存放在總部,在總部只需完成接收售票點的出票請求來完成增減票餘量併產生惟一票號分發給售票點,而後各售票點將票賣給旅客(因此這個模型的通俗的理解就是各個售票點代替旅客去售票總部排隊申請出票,這樣就不會出現同一張票賣給多個旅客),這也就是同步與互斥的一個案例吧。算法
這裏講解一個使用Java實現這個案例的代碼吧多線程
很明顯這裏各個售票點銷售的都是售票總部的票餘量,因此各個售票點須要共享票餘量這個變量。於是咱們能夠建立一個售票窗口類併發
class TicketsWindows implements Runnable{ private int ticketsNums = 2000; public void run(){ while(true){ //同步代碼塊,至關於一個事務,至關於售票總部完成的工做 synchronized(this){ //判斷票餘量 if(ticketsNums>0){ System.out.println(Thread.currentThread().getName() + "正在銷售第" + (2000-ticketsNums+1) + "張票"); try { Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } ticketsNums--; }else{ System.out.println("票已售罄,請購買其餘時間的票!!!"); break; } } } } }
而後咱們在主類裏面建立一個售票窗口對象,多個線程對象來共享這個售票窗口對象來模擬多個售票代售點學習
public class MainActivity { public static void main(String []args){ TicketsWindows tw1 = new TicketsWindows(); Thread t1 = new Thread(tw1); Thread t2 = new Thread(tw1); Thread t3 = new Thread(tw1); t1.start(); t2.start(); t3.start(); } }
這裏咱們建立一個售票窗口對象做爲售票總部,裏面的同步塊就是各代售點向售票總部提出出票申請後售票總部完成票餘量增減產生票號出票的操做,中間使用synchronized關鍵字來定義一個同步塊,this表示當前同步塊。我在售票窗口類中增減票餘量後使用線程休眠來體現可能出現的同時多個線程來訂票,如此更能體現出多線程同步互斥的現象。this
總結:其實從多線程以及以前學習操做系統時的同步互斥問題和併發並行,這裏我想說一點就是所謂的併發若是按我我的的理解這只是一個宏觀的問題,在微觀上仍是有前後順序的,也就是說當只有一個cpu或者1核其實際上在同一時刻只可能會處理一個問題,也就是說咱們在理解這些同步互斥併發的時候都是基於使用必定的算法來完成將一件事情分紅多個更小的事情來與其餘事情分解成的小事情交替完成從而達到併發的目的。spa