最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java實現(xiàn)排隊論的原理

 更新時間:2016年02月01日 17:02:38   作者:xiaojimanman  
這篇文章主要為大家詳細(xì)介紹了Java實現(xiàn)排隊論的原理,對排隊論感興趣的小伙伴們可以參考一下

引入:

前段時間去銀行辦業(yè)務(wù),排隊的人那是真多,自己正式辦理業(yè)務(wù)也就不到5分鐘,但是卻足足等了兩個小時(相信很多人都遇到過這種情況),對這種服務(wù)水平真的是無語了,但是問題又來了,銀行應(yīng)該開幾個窗口,既能保證整體的服務(wù)質(zhì)量,又能保證資源資源的利用率呢?下面我們就通過排隊論來模擬這個問題。

排隊論簡介

      排隊論是研究系統(tǒng)隨機(jī)聚散現(xiàn)象和隨機(jī)系統(tǒng)工作工程的數(shù)學(xué)理論和方法,又稱隨機(jī)服務(wù)系統(tǒng)理論,為運(yùn)籌學(xué)的一個分支。我們下面對排隊論做下簡化處理,先看下圖:

      我們在圖的左側(cè)安排若干個藍(lán)色服務(wù)臺,右側(cè)為可能會過來的紅色顧客,中間為黃色的等候區(qū),如果有服務(wù)臺處于空閑狀態(tài),顧客可以直接去接受服務(wù),否則就要在黃色區(qū)域等候,顧客服務(wù)的順序采用先到現(xiàn)服務(wù)的原則,現(xiàn)在如果我們知道顧客過來的概率分布,那么我們在左側(cè)安排幾個服務(wù)臺既能達(dá)到更好的服務(wù)水平,又能保證服務(wù)臺的使用率?下面我們就構(gòu)建模型來模擬這個問題。

排隊論分步實現(xiàn)

1)對于排隊論,我們首先要確定顧客屬性,知道顧客什么時候到達(dá),需要的服務(wù)耗時等,我們首先創(chuàng)建一個顧客類,在這里我們指定了顧客服務(wù)的最大、最小時間,這里我們?yōu)榱撕喕椭苯诱J(rèn)為服務(wù)時間完全隨機(jī):

public class CustomerBean { 
 //最小服務(wù)時間 
 private static int minServeTime = 3 * 1000; 
 //最大服務(wù)時間 
 private static int maxServeTime = 15 * 1000; 
 //顧客達(dá)到時間 
 private long arriveTime; 
 //顧客需要服務(wù)耗時 
 private int serveTime; 
  
 public CustomerBean() { 
  //設(shè)置到達(dá)時間 
  arriveTime = System.currentTimeMillis(); 
  //隨機(jī)設(shè)置顧客的服務(wù)時間 
  serveTime = (int) (Math.random() * (maxServeTime - minServeTime) + minServeTime); 
 } 
} 

2)上面我們定義了顧客,緊接著就需要定義一個排隊隊列,我們先看下隊列的屬性,這里我們定義一個數(shù)組,用它來保存排隊的顧客,定義下一個顧客到來的最小、最大時間間隔以及顧客來不來的概率(這里簡單說明下,如果下一個顧客的間隔時間是3,但是通過概率計算并為滿足,則這個顧客不進(jìn)入隊列,這樣設(shè)置的原因是盡可能的使顧客達(dá)到有很大的隨機(jī)性)和隊列中最大的排隊人數(shù)。

public class CustomerQuene { 
 //等待顧客隊列 
 private LinkedList<CustomerBean> customers = new LinkedList<CustomerBean>(); 
 //下一個顧客過來最短時間 
 private int minTime = 0; 
 //下一個顧客過來最大時間 
 private int maxTime = 1 * 1000; 
 //來顧客的概率 
 private double rate = 0.9; 
 //標(biāo)識是否繼續(xù)產(chǎn)生顧客 
 private boolean flag = true; 
 //最大排隊人數(shù) 
 private int maxWaitNum = 0; 
} 

3)顧客和排隊的隊列都有了,我們就設(shè)置一個產(chǎn)生顧客的線程,讓它不斷的產(chǎn)生顧客,這里就有我們上面說的時間和概率分布。

/** 
 *@Description: 生成顧客線程 
 *@Version:1.1.0 
 */ 
private class CustomerThread extends Thread { 
 private CustomerThread(String name) { 
  super(name); 
 } 
 
 @Override 
 public void run() { 
  while (flag) { 
   //隊尾添加一個新顧客 
   if (Math.random() < rate) { 
    customers.addLast(new CustomerBean()); 
    if (maxWaitNum < customers.size()) { 
     maxWaitNum = customers.size(); 
    } 
   } 
   int sleepTime = (int) (Math.random() * (maxTime - minTime) + minTime); 
   try { 
    TimeUnit.MILLISECONDS.sleep(sleepTime); 
   } catch (Exception e) { 
    e.printStackTrace(); 
   } 
  } 
 } 
} 

4)如果隊列中有顧客排隊切有空閑的服務(wù)臺,就需要獲取隊頭的顧客去接受服務(wù)

public synchronized CustomerBean getCustomerBean() { 
 if (customers == null || customers.size() < 1) { 
  return null; 
 } 
 return customers.removeFirst(); 
} 

5)顧客相關(guān)的屬性和方法都已經(jīng)準(zhǔn)備好,下面就設(shè)置下服務(wù)臺相關(guān)的屬性,這里我們直接把服務(wù)臺設(shè)置成線程,定義一些服務(wù)指標(biāo),如服務(wù)的顧客數(shù)目、總等待時間、總服務(wù)時間、最大等待時間等。

public class ServantThread extends Thread{ 
 //服務(wù)顧客數(shù)目 
 private static int customerNum = 0; 
 //總等待時間 
 private static int sumWaitTime = 0; 
 //總服務(wù)時間 
 private static int sumServeTime = 0; 
 //最大等待時間 
 private static int maxWaitTime = 0; 
 private boolean flag = false; 
 private String name; 
} 

6)服務(wù)臺最主要的工作就是服務(wù)顧客,這里我們把服務(wù)顧客相關(guān)的操作寫到線程的run方法中。

public void run() { 
 flag = true; 
 while (flag) { 
  CustomerBean customer = CustomerQuene.getCustomerQuene().getCustomerBean(); 
  //如果顧客線程已經(jīng)關(guān)閉且隊列中沒有顧客,服務(wù)臺線程關(guān)閉釋放 
  if (customer == null) { 
   if (!CustomerQuene.getCustomerQuene().isFlag()) { 
    flag = false; 
    print(); 
   } 
   continue; 
  } 
  long now = System.currentTimeMillis(); 
  int waitTime = (int) (now - customer.getArriveTime()); 
  //保存最大的等待時間 
  if (waitTime > maxWaitTime) { 
   maxWaitTime = waitTime; 
  } 
  //睡眠時間為顧客的服務(wù)時間,代表這段時間在服務(wù)顧客 
  try { 
   TimeUnit.MILLISECONDS.sleep(customer.getServeTime()); 
  } catch (Exception e) { 
   e.printStackTrace(); 
  } 
  System.err.println(name + " 服務(wù)顧客耗時:" + customer.getServeTime() + "ms\t顧客等待:" + waitTime + "ms"); 
  customerNum++; 
  sumWaitTime += waitTime; 
  sumServeTime += customer.getServeTime(); 
   
 } 
} 

7)最后我們編寫一個測試模型,來驗證服務(wù)水平

 /** 
 *@Description:  
 */ 
package com.lulei.opsearch.quene; 
 
import java.util.concurrent.TimeUnit; 
 
public class Test { 
 
 public static void main(String[] args) { 
  //開門 
  System.out.println("開門接客啦!"); 
  boolean flag = true; 
  CustomerQuene.getCustomerQuene(); 
  long a = System.currentTimeMillis(); 
  int servantNum = 10; 
  for (int i = 0; i < servantNum; i++) { 
   ServantThread thread = new ServantThread("服務(wù)臺" + i); 
   thread.start(); 
  } 
  while (flag) { 
   long b = System.currentTimeMillis(); 
   if (b - a > 1 * 60 * 1000 && flag) { 
    //關(guān)門 
    flag = false; 
    CustomerQuene.getCustomerQuene().close(); 
    System.out.println("關(guān)門不接客啦!"); 
   } 
   System.out.println("系統(tǒng)運(yùn)行時間:" + (b -a) + "ms"); 
   System.out.println("系統(tǒng)空閑時間:" + ((b -a) * servantNum - ServantThread.getSumServeTime())); 
   ServantThread.print(); 
   try { 
    TimeUnit.SECONDS.sleep(2); 
   } catch (Exception e) { 
    e.printStackTrace(); 
   } 
  } 
 } 
 
} 

運(yùn)行結(jié)果
1)運(yùn)行開始

2)顧客產(chǎn)生線程關(guān)閉

3)最后服務(wù)水平

通過修改服務(wù)臺的個數(shù)就可以評估在當(dāng)前的顧客情況下應(yīng)該設(shè)置幾個服務(wù)臺。

完整代碼

1)顧客類

 /** 
 *@Description:  
 */ 
package com.lulei.opsearch.quene; 
 
public class CustomerBean { 
 //最小服務(wù)時間 
 private static int minServeTime = 3 * 1000; 
 //最大服務(wù)時間 
 private static int maxServeTime = 15 * 1000; 
 //顧客達(dá)到時間 
 private long arriveTime; 
 //顧客需要服務(wù)耗時 
 private int serveTime; 
  
 public CustomerBean() { 
  //設(shè)置到達(dá)時間 
  arriveTime = System.currentTimeMillis(); 
  //隨機(jī)設(shè)置顧客的服務(wù)時間 
  serveTime = (int) (Math.random() * (maxServeTime - minServeTime) + minServeTime); 
 } 
 
 public static int getMinServeTime() { 
  return minServeTime; 
 } 
 
 public static void setMinServeTime(int minServeTime) { 
  CustomerBean.minServeTime = minServeTime; 
 } 
 
 public static int getMaxServeTime() { 
  return maxServeTime; 
 } 
 
 public static void setMaxServeTime(int maxServeTime) { 
  CustomerBean.maxServeTime = maxServeTime; 
 } 
 
 public long getArriveTime() { 
  return arriveTime; 
 } 
 
 public void setArriveTime(long arriveTime) { 
  this.arriveTime = arriveTime; 
 } 
 
 public int getServeTime() { 
  return serveTime; 
 } 
 
 public void setServeTime(int serveTime) { 
  this.serveTime = serveTime; 
 } 
} 

2)顧客隊列

 /** 
 *@Description:  
 */ 
package com.lulei.opsearch.quene; 
 
import java.util.LinkedList; 
import java.util.concurrent.TimeUnit; 
 
public class CustomerQuene { 
 //等待顧客隊列 
 private LinkedList<CustomerBean> customers = new LinkedList<CustomerBean>(); 
 //下一個顧客過來最短時間 
 private int minTime = 0; 
 //下一個顧客過來最大時間 
 private int maxTime = 1 * 1000; 
 //來顧客的概率 
 private double rate = 0.9; 
 //標(biāo)識是否繼續(xù)產(chǎn)生顧客 
 private boolean flag = true; 
 //最大排隊人數(shù) 
 private int maxWaitNum = 0; 
  
 public int getMaxWaitNum() { 
  return maxWaitNum; 
 } 
  
 public boolean isFlag() { 
  return flag; 
 } 
 
 /** 
  * @return 
  * @Author:lulei 
  * @Description: 獲取排在隊頭的顧客 
  */ 
 public synchronized CustomerBean getCustomerBean() { 
  if (customers == null || customers.size() < 1) { 
   return null; 
  } 
  return customers.removeFirst(); 
 } 
  
 public void close() { 
  if (flag) { 
   flag = false; 
  } 
 } 
  
 /** 
  * @return 
  * @Author:lulei 
  * @Description: 獲取等待顧客數(shù)量 
  */ 
 public int getWaitCustomerNum() { 
  return customers.size(); 
 } 
  
 /** 
  *@Description: 生成顧客線程 
  *@Version:1.1.0 
  */ 
 private class CustomerThread extends Thread { 
  private CustomerThread(String name) { 
   super(name); 
  } 
 
  @Override 
  public void run() { 
   while (flag) { 
    //隊尾添加一個新顧客 
    if (Math.random() < rate) { 
     customers.addLast(new CustomerBean()); 
     if (maxWaitNum < customers.size()) { 
      maxWaitNum = customers.size(); 
     } 
    } 
    int sleepTime = (int) (Math.random() * (maxTime - minTime) + minTime); 
    try { 
     TimeUnit.MILLISECONDS.sleep(sleepTime); 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 
   } 
  } 
 } 
 
 //單例模式開始 
 private static class CustomerQueneDao { 
  private static CustomerQuene customerQuene = new CustomerQuene(); 
 } 
 private CustomerQuene() { 
  CustomerThread customerThread = new CustomerThread("顧客產(chǎn)生線程"); 
  customerThread.start(); 
 } 
 public static CustomerQuene getCustomerQuene() { 
  return CustomerQueneDao.customerQuene; 
 } 
 //單例模式結(jié)束 
  
 public int getMinTime() { 
  return minTime; 
 } 
  
 public void setMinTime(int minTime) { 
  this.minTime = minTime; 
 } 
  
 public int getMaxTime() { 
  return maxTime; 
 } 
  
 public void setMaxTime(int maxTime) { 
  this.maxTime = maxTime; 
 } 
 
 public double getRate() { 
  return rate; 
 } 
 
 public void setRate(double rate) { 
  this.rate = rate; 
 } 
} 

3)服務(wù)臺線程

 /** 
 *@Description:  
 */ 
package com.lulei.opsearch.quene; 
 
import java.util.concurrent.TimeUnit; 
 
import com.lulei.util.ParseUtil; 
 
public class ServantThread extends Thread{ 
 //服務(wù)顧客數(shù)目 
 private static int customerNum = 0; 
 //總等待時間 
 private static int sumWaitTime = 0; 
 //總服務(wù)時間 
 private static int sumServeTime = 0; 
 //最大等待時間 
 private static int maxWaitTime = 0; 
 private boolean flag = false; 
 private String name; 
  
 public ServantThread(String name) { 
  super(name); 
  this.name = name; 
 } 
  
 public static int getMaxWaitTime() { 
  return maxWaitTime; 
 } 
 
 public static int getSumServeTime() { 
  return sumServeTime; 
 } 
 
 @Override 
 public void run() { 
  flag = true; 
  while (flag) { 
   CustomerBean customer = CustomerQuene.getCustomerQuene().getCustomerBean(); 
   //如果顧客線程已經(jīng)關(guān)閉且隊列中沒有顧客,服務(wù)臺線程關(guān)閉釋放 
   if (customer == null) { 
    if (!CustomerQuene.getCustomerQuene().isFlag()) { 
     flag = false; 
     print(); 
    } 
    continue; 
   } 
   long now = System.currentTimeMillis(); 
   int waitTime = (int) (now - customer.getArriveTime()); 
   //保存最大的等待時間 
   if (waitTime > maxWaitTime) { 
    maxWaitTime = waitTime; 
   } 
   //睡眠時間為顧客的服務(wù)時間,代表這段時間在服務(wù)顧客 
   try { 
    TimeUnit.MILLISECONDS.sleep(customer.getServeTime()); 
   } catch (Exception e) { 
    e.printStackTrace(); 
   } 
   System.err.println(name + " 服務(wù)顧客耗時:" + customer.getServeTime() + "ms\t顧客等待:" + waitTime + "ms"); 
   customerNum++; 
   sumWaitTime += waitTime; 
   sumServeTime += customer.getServeTime(); 
    
  } 
 } 
  
 public static void print() { 
  if (customerNum > 0) { 
   System.out.println("--------------------------------------"); 
   System.out.println("服務(wù)顧客數(shù)目:" + customerNum); 
   System.out.println("最大等待時間:" + maxWaitTime); 
   System.out.println("等待顧客數(shù)目:" + CustomerQuene.getCustomerQuene().getWaitCustomerNum()); 
   System.out.println("最大等待顧客數(shù)目:" + CustomerQuene.getCustomerQuene().getMaxWaitNum()); 
   //輸出顧客平均等待時間,保留兩位小數(shù) 
   System.out.println("顧客平均等待時間:" + ParseUtil.parseDoubleToDouble((sumWaitTime * 1.0 / customerNum), 2) + "ms"); 
   System.out.println("顧客平均服務(wù)時間:" + ParseUtil.parseDoubleToDouble((sumServeTime * 1.0 / customerNum), 2) + "ms"); 
   System.out.println("系統(tǒng)總服務(wù)時間:" + sumServeTime + "ms"); 
  } 
 } 
} 

4)測試模型

 /** 
 *@Description:  
 */ 
package com.lulei.opsearch.quene; 
 
import java.util.concurrent.TimeUnit; 
 
public class Test { 
 
 public static void main(String[] args) { 
  //開門 
  System.out.println("開門接客啦!"); 
  boolean flag = true; 
  CustomerQuene.getCustomerQuene(); 
  long a = System.currentTimeMillis(); 
  int servantNum = 10; 
  for (int i = 0; i < servantNum; i++) { 
   ServantThread thread = new ServantThread("服務(wù)臺" + i); 
   thread.start(); 
  } 
  while (flag) { 
   long b = System.currentTimeMillis(); 
   if (b - a > 1 * 60 * 1000 && flag) { 
    //關(guān)門 
    flag = false; 
    CustomerQuene.getCustomerQuene().close(); 
    System.out.println("關(guān)門不接客啦!"); 
   } 
   System.out.println("系統(tǒng)運(yùn)行時間:" + (b -a) + "ms"); 
   System.out.println("系統(tǒng)空閑時間:" + ((b -a) * servantNum - ServantThread.getSumServeTime())); 
   ServantThread.print(); 
   try { 
    TimeUnit.SECONDS.sleep(2); 
   } catch (Exception e) { 
    e.printStackTrace(); 
   } 
  } 
 } 
 
} 

以上就是關(guān)于Java實現(xiàn)排隊論的原理詳細(xì)介紹,希望對大家的學(xué)習(xí)有所幫助。

相關(guān)文章

  • 妙解Java中的回調(diào)機(jī)制(CallBack)

    妙解Java中的回調(diào)機(jī)制(CallBack)

    本文以最簡明扼要的例子將Java的回調(diào)機(jī)制介紹給大家,感興趣的朋友可以參考一下。
    2016-07-07
  • Java線程休眠_(dá)動力節(jié)點Java學(xué)院整理

    Java線程休眠_(dá)動力節(jié)點Java學(xué)院整理

    sleep() 的作用是讓當(dāng)前線程休眠,即當(dāng)前線程會從“運(yùn)行狀態(tài)”進(jìn)入到“休眠(阻塞)狀態(tài)”。下面通過實例代碼給大家介紹Java線程休眠的知識,需要的朋友參考下吧
    2017-05-05
  • Java多線程環(huán)境下死鎖模擬

    Java多線程環(huán)境下死鎖模擬

    這篇文章主要介紹了模擬Java多線程環(huán)境下的死鎖,文章介紹一些死鎖的產(chǎn)生條件的相關(guān)資料,具有一定的參考價值,需要的小伙伴可以參考一下,希望對你有所幫助
    2021-12-12
  • SpringBoot框架中Mybatis-plus的簡單使用操作匯總

    SpringBoot框架中Mybatis-plus的簡單使用操作匯總

    這篇文章主要介紹了SpringBoot框架中Mybatis-plus的簡單使用,本文通過示例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-02-02
  • Java TreeSet 添加失敗的解決

    Java TreeSet 添加失敗的解決

    這篇文章主要介紹了Java TreeSet 添加失敗的解決,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-09-09
  • SpringSceurity實現(xiàn)短信驗證碼登陸

    SpringSceurity實現(xiàn)短信驗證碼登陸

    這篇文章主要介紹了SpringSceurity實現(xiàn)短信驗證碼登陸,本文通過實例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-06-06
  • RabbitMq報錯reply-code=406 reply-text=PRECONDITION_FAILED解決

    RabbitMq報錯reply-code=406 reply-text=PRECONDITION_FAILED

    這篇文章主要為大家介紹了RabbitMq報錯reply-code=406 reply-text=PRECONDITION_FAILED分析解決,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-12-12
  • Java中Map和Set的常見用法舉例

    Java中Map和Set的常見用法舉例

    Map和Set是一種專門用來進(jìn)行搜索的容器或者數(shù)據(jù)結(jié)構(gòu),其具體效率與具體的實例化子類有關(guān),下面這篇文章主要給大家介紹了關(guān)于Java中Map和Set的常見用法,需要的朋友可以參考下
    2024-04-04
  • Spring Bean常用的的裝配方式詳解

    Spring Bean常用的的裝配方式詳解

    這篇文章主要介紹了Spring Bean常用的的裝配方式詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2019-07-07
  • Springboot項目通過redis實現(xiàn)接口的冪等性

    Springboot項目通過redis實現(xiàn)接口的冪等性

    這篇文章主要為大家介紹了Springboot項目通過redis實現(xiàn)接口的冪等性,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-12-12

最新評論

泗水县| 阿拉善盟| 青海省| 凤山市| 齐齐哈尔市| 资阳市| 聊城市| 黄梅县| 普兰县| 张家口市| 长沙县| 余江县| 绥芬河市| 儋州市| 株洲县| 金门县| 凤凰县| 汪清县| 搜索| 屏山县| 廉江市| 乌兰浩特市| 民权县| 永吉县| 微博| 湘阴县| 龙泉市| 鄂托克前旗| 健康| 共和县| 塔河县| 华宁县| 郸城县| 安平县| 桓台县| 乌拉特后旗| 三江| 诸城市| 江孜县| 滕州市| 丽江市|