案例:
售貨員賣票問題,一個旅游景點有40張票,開啟了兩個買票的窗口,請用線程的方式,進行模擬售貨員賣票過程,並進行分析。
思路:景點的40張票是一個共享票池,當進行售票時,進行票數確認售票和票數-1,為保證賣的票不是同一張票,必須進行加鎖並進行票數判斷
使兩個線程共用一個安全的數據,保障數據安全。
//線程函數:MyThread3.java
/** * 售票線程 * 進行售票線程的模擬,利用Runnable接口實現重寫run方法,保證線程的安全 * @author [Light](必須) * @see [run()](可選) * @since [version 1.0] (必須) */ public class MyThread3 implements Runnable{ //售票數 int num=40; //設置鎖旗標 Object lock=new Object(); @Override public void run() { // TODO Auto-generated method stub //循環開始售票 while(num>0){ //進行加鎖,獲取鎖 synchronized (lock) { //判斷是否售完 if(num>0) { //模擬售票過程 System.out.println(Thread.currentThread().getName()+ "賣出第"+num+"張票"); num--; } try { //進行睡眠,暫時放棄cpu的使用,但不釋放鎖 Thread.currentThread().sleep(500); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } }
//主函數MyTest.java /************************************************************ Copyright (C), 1988-1999, Huawei Tech. Co., Ltd. FileName: Mytest.java Author: Light Version : version1.0 Date: 2018/7/11 Description: //模擬售貨員售票 Version: // 版本信息 1.開啟兩個進程,通過Runnable接口實現多線程 2.保證兩個進程公用一個售票參數 Function List: // 主要函數及其功能 1.Thred3售票線程 2.Thred3.start();開啟線程 History: // 歷史修改記錄 <author> <time> <version > <desc> Light 2018/7/11 1.0 build this moudle ***********************************************************/ public class MyTest { //主函數 public static void main(String[] args) { // TODO Auto-generated method stub //創建MyThread3線程 Runnable myThread3=new MyThread3(); //開啟兩個線程 Thread t1=new Thread(myThread3); Thread t2=new Thread(myThread3); t1.start(); t2.start(); } }
最終的運行結果:
從結果可以看出,開啟的兩個線程公用了同一個售票池,進行售票,通過加鎖,實現了每一張票對每一人的售賣,最終進行示例的模擬。