Introducido:
Hace algún tiempo, fui al banco para manejar los negocios, y había tanta gente en la fila. Tomó menos de 5 minutos manejar los negocios solo, pero esperé dos horas (creo que muchas personas han encontrado esta situación). Me quedé sin palabras sobre este nivel de servicio, pero el problema surge nuevamente. ¿El banco debe abrir varias ventanas para garantizar la calidad general del servicio y la tasa de utilización de recursos? A continuación, simularemos este problema a través de la teoría de la cola.
Introducción a la teoría de la cola
La teoría de colas es una teoría y método matemático que estudia el fenómeno de la recopilación aleatoria y la dispersión de los sistemas y la ingeniería de trabajo de los sistemas aleatorios. También se conoce como la teoría de los sistemas de servicios aleatorios, y es una rama de la investigación de operaciones. Simplifiquemos la teoría de colas a continuación y primero veamos la siguiente figura:
Organizamos varios escritorios de servicio azul en el lado izquierdo de la imagen, con clientes rojos que pueden venir a la derecha y un área de espera amarilla en el medio. Si un escritorio de servicio está inactivo, los clientes pueden recibir directamente los servicios, de lo contrario tienen que esperar en el área amarilla. El orden de servicio al cliente adopta el principio del servicio actual y actual. Ahora, si conocemos la distribución de probabilidad de los clientes, ¿cómo podemos organizar varios escritorios de servicio a la izquierda para lograr un mejor nivel de servicio y garantizar la tasa de uso del escritorio de servicio? A continuación, construiremos un modelo para simular este problema.
La teoría de colas se implementa paso a paso
1) Para la teoría de colas, primero debemos determinar los atributos del cliente, saber cuándo llega el cliente, el tiempo de servicio requerido, etc. Primero creamos una clase de cliente, donde especificamos el tiempo máximo y mínimo para el servicio al cliente. Aquí, para simplificar, pensamos directamente que el tiempo de servicio es completamente aleatorio:
Clase pública CustomerBean {// Tiempo de servicio mínimo Private Static int minservetime = 3 * 1000; // Tiempo de servicio máximo Private static int maxServeTime = 15 * 1000; // El cliente alcanza el tiempo privado Long Lirivetime; // Tiempo de servicio de necesidades del cliente Private int servetime; public customerBean () {// Establecer tiempo de llegada Llegación = System.CurrentTimemillis (); // Conjunto aleatorio Tiempo de servicio al cliente Servetime = (int) (Math.random () * (maxserveTime - minserveTime) + minserveTime); }} 2) Definimos el cliente anterior, y luego necesitamos definir una cola de cola. Primero veamos los atributos de la cola. Aquí definimos una matriz para salvar a los clientes en cola, definir los intervalos de tiempo mínimo y máximo para que llegue el próximo cliente y la probabilidad de que el cliente venga (se explique brevemente aquí, si el tiempo de intervalo del próximo cliente es 3, pero se calcula a través de la probabilidad y satisfecho, el cliente no ingresará la cola.
Clase pública Customerquene {// Esperando cola de clientes Private LinkedList <CustomerBean> CLIENDS = new LinkedList <CustomerBean> (); // El tiempo más corto para que el próximo cliente venga privado int Mintime = 0; // El tiempo máximo para que el próximo cliente venga privado int maxteMe = 1 * 1000; // La probabilidad de los clientes vituantes de los clientes Private Double Tasa = 0.9; // Identificar si la bandera booleana privada del cliente = verdadero; // El número máximo de personas en cola private int maxwaitnum = 0; } 3) Cuando hay clientes y colas, configuramos un hilo para generar clientes para generar continuamente clientes. Aquí están las distribuciones de tiempo y probabilidad que mencionamos anteriormente.
/ ***@Descripción: Genere el hilo del cliente*@versión: 1.1.0*/ private Clase CustomerThread extiende el hilo {privado con customthread (nombre de cadena) {super (nombre); } @Override public void run () {while (flag) {// Agregue un nuevo cliente al final del equipo if (math.random () <rate) {customers.addlast (nuevo customerBean ()); if (maxwaitnum <chows.size ()) {maxwaitnum = chows.size (); }} int sleeptime = (int) (math.random () * (maxteMe - Mintime) + Mintime); intente {TimeUnit.milliseConds.sleep (Sleeptime); } catch (Exception e) {E.PrintStackTrace (); }}}}} 4) Si hay clientes en la cola que hace cola para cortar en el mostrador de servicio gratuito, debe lograr que el cliente esté a la cabeza del equipo que reciba el servicio.
Public sincronizado CustomerBean getCustomerBean () {if (clientes == NULL || CLIENDS.SIZE () <1) {return null; } return cients.removeFirst (); } 5) Los atributos y métodos relacionados con el cliente están listos. Establezcamos los atributos relacionados con el escritorio de servicio. Aquí establecemos directamente el escritorio de servicio en un hilo para definir algunos indicadores de servicio, como la cantidad de clientes atendidos, el tiempo de espera total, el tiempo total de servicio, el tiempo de espera máximo, etc.
Public Class ServantThread extiende el hilo {// Número de clientes de servicios privados static int customernum = 0; // Tiempo de espera total privado static int sumwaittime = 0; // Tiempo total de servicio Private static int sumserveTime = 0; // Tiempo de espera máximo Private static int maxwaittime = 0; bandera booleana privada = falso; nombre de cadena privada; } 6) El trabajo principal de la mesa de servicio es servir a los clientes. Aquí escribimos operaciones relacionadas con servir a los clientes en el método Ejecutar del hilo.
public void run () {flag = true; while (flag) {customerBean Customer = CustomerQuene.getCustomerQuee (). GetCustomerBean (); // Si el hilo del cliente se ha cerrado y no hay clientes en la cola, el hilo del escritorio de servicio se cierra y libera si (customer == null) {if (! Customquene.getCustomerquene (). IsFlag ()) {flag = false; imprimir(); } continuar; } long Now = System.CurrentTimemillis (); int waittime = (int) (ahora - customer.getarriveTime ()); // Guardar el tiempo de espera máximo si (waittime> maxwaittime) {maxwaittime = waittime; } // El tiempo de sueño es el tiempo de servicio del cliente, que representa el período de servicio durante este período de tiempo atendiendo a los clientes. Intente {timeUnit.milliseConds.sleep (customer.getServeTime ()); } catch (Exception e) {E.PrintStackTrace (); } System.err.println (nombre + "Tiempo para servir a los clientes:" + Customer.getServesServeTime () + "MS/T Cliente en espera:" + WaitTime + "MS"); Customernum ++; sumwaittime += waitteMe; sumserveTime += customer.getServeTime (); }} 7) Finalmente, escribimos un modelo de prueba para verificar el nivel de servicio
/ ** *@Descripción: */ paquete com.lulei.opsearch.quene; import java.util.concurrent.timeunit; Prueba de clase pública {public static void main (string [] args) {// abre la puerta system.out.println ("¡Abre la puerta y recoge a los clientes!"); bandera booleana = verdadero; Customerquene.getCustomerquene (); largo a = System.CurrentTimemillis (); int servicenum = 10; for (int i = 0; i <ServiceNum; i ++) {ServantThread Thread = New ServantThread ("Desk Service"+I); Thread.Start (); } while (flag) {long b = system.currentTimemillis (); if (b - a> 1 * 60 * 1000 && flag) {// cerrar flag = false; CustomerQuene.getCustomerquene (). Close (); System.out.println ("¡Cierra la puerta y no recoja a los clientes!"); } System.out.println ("Tiempo de ejecución del sistema:" + (b -a) + "ms"); System.out.println ("Tiempo de inactividad del sistema:" + ((b -a) * Servantnum - ServantThread.getSumServeTime ())); ServantThread.print (); intente {TimeUnit.seconds.sleep (2); } catch (Exception e) {E.PrintStackTrace (); }}}} Resultados de ejecución
1) Inicio de la operación
2) El cliente genera el cierre de hilos
3) Nivel de servicio final
Al modificar la cantidad de escritorios de servicio, puede evaluar cuántos escritorios de servicio se deben configurar en la situación actual del cliente.
Código completo
1) Categoría de clientes
/ ** *@Descripción: */ paquete com.lulei.opsearch.quene; Clase pública CustomerBean {// Tiempo de servicio mínimo Private Static int minservetime = 3 * 1000; // Tiempo de servicio máximo Private static int maxServeTime = 15 * 1000; // El cliente alcanza el tiempo privado Long Lirivetime; // Tiempo de servicio de necesidades del cliente Private int servetime; public customerBean () {// Establecer tiempo de llegada ArriveTime = System.CurrentTimemillis (); // Establecer al azar el tiempo de servicio al cliente 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) cola de clientes
/ ** *@Descripción: */ paquete com.lulei.opsearch.quene; import java.util.linkedlist; import java.util.concurrent.timeunit; Clase pública Customerquene {// Esperando cola de clientes Private LinkedList <CustomerBean> CLIENDS = new LinkedList <CustomerBean> (); // El tiempo más corto para que el próximo cliente venga privado int Mintime = 0; // El tiempo máximo para que el próximo cliente venga privado int maxteMe = 1 * 1000; // La probabilidad de venir al cliente Tasa doble privada = 0.9; // Identificar si los clientes continúan generando una bandera booleana privada = true; // Número máximo de personas en cola private int maxwaitnum = 0; public int getMaxWaitnum () {return maxwaitnum; } public boolean isFlag () {Bandera de retorno; } / ** * @return * @author: lulei * @Description: obtenga al cliente en la cabeza de la cola * / public sincronizado customerbean getCustomerBean () {if (clientes == null || cients.size () <1) {return null; } return cients.removeFirst (); } public void Close () {if (flag) {flag = false; }} / ** * @return * @author: lulei * @Description: Obtenga el número de clientes que esperan * / public int getWaitCustomernum () {return cients.size (); } / ***@Descripción: Genere el hilo del cliente*@versión: 1.1.0* / private Clase CustomerThread extiende el hilo {privado cliente (nombre de cadena) {super (nombre); } @Override public void run () {while (flag) {// Agregue un nuevo cliente al final del equipo if (math.random () <rate) {customers.addlast (nuevo customerBean ()); if (maxwaitnum <chows.size ()) {maxwaitnum = chows.size (); }} int sleeptime = (int) (math.random () * (maxteMe - Mintime) + Mintime); intente {TimeUnit.milliseConds.sleep (Sleeptime); } catch (Exception e) {E.PrintStackTrace (); }}}}} // Modo Singleton Inicie la clase estática privada Customerquenedao {private static customerquene customerQuene = new CustomerQuene (); } private CustomerQuene () {CustomerThread CustomerThread = New CustomerThread ("Hilo de generación de clientes"); CustomerThread.start (); } public static CustomerQuene getCustomerquene () {return customerquenedao.customerquene; } // Singleton Mode End public int getMintime () {return Mintime; } public void setMintime (int Mintime) {this.Mintime = Mintime; } public int getMoxTime () {return maxtime; } public void setMaXTime (int maxteMe) {this.mextime = maxtime; } public doble getRate () {tasa de retorno; } public void setRate (doble tasa) {this.rate = rate; }} 3) Hilo del escritorio de servicio
/ ** *@Descripción: */ paquete com.lulei.opsearch.quene; import java.util.concurrent.timeunit; import com.lulei.util.parseutil; Public Class ServantThread extiende el hilo {// Número de clientes de servicios privados static int customernum = 0; // Tiempo de espera total privado static int sumwaittime = 0; // Tiempo total de servicio Private static int sumserveTime = 0; // Tiempo de espera máximo Private static int maxwaittime = 0; bandera booleana privada = falso; nombre de cadena privada; public ServantThread (nombre de cadena) {super (nombre); 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.getCustomerQuee (). GetCustomerBean (); // Si el hilo del cliente se ha cerrado y no hay clientes en la cola, el hilo del escritorio de servicio se cierra y libera si (customer == null) {if (! Customquene.getCustomerquene (). IsFlag ()) {flag = false; imprimir(); } continuar; } long Now = System.CurrentTimemillis (); int waittime = (int) (ahora - customer.getarriveTime ()); // Guardar el tiempo de espera máximo si (waittime> maxwaittime) {maxwaittime = waittime; } // El tiempo de sueño es el tiempo de servicio del cliente, que representa el try del cliente {TimeUnit.milliseconds.sleep (Customer.getServeTime ()); } catch (Exception e) {E.PrintStackTrace (); } System.err.println (nombre + "Tiempo para servir a los clientes:" + Customer.getServeTime () + "MS/T Cliente esperando:" + Waittime + "MS"); Customernum ++; sumwaittime += waitteMe; sumserveTime += customer.getServeTime (); }} public static void print () {if (Customernum> 0) { System.out.println ("----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- --------------------------------------------------------------------------------------------------- // emite el tiempo de espera promedio del cliente y retiene dos lugares decimales System.out.println ("Tiempo de espera promedio para los clientes:" + parseutil.parsedoubletodouble ((sumwaittime * 1.0 /customernum), 2) + "ms"); Customernum), 2) + "MS"); 4) Prueba el modelo
/ ** *@Descripción: */ paquete com.lulei.opsearch.quene; import java.util.concurrent.timeunit; Prueba de clase pública {public static void main (string [] args) {// abre la puerta system.out.println ("¡Abre la puerta y recoge a los clientes!"); bandera booleana = verdadero; Customerquene.getCustomerquene (); largo a = System.CurrentTimemillis (); int servicenum = 10; for (int i = 0; i <ServiceNum; i ++) {ServantThread Thread = New ServantThread ("Desk Service"+I); Thread.Start (); } while (flag) {long b = system.currentTimemillis (); if (b - a> 1 * 60 * 1000 && flag) {// cerrar flag = false; CustomerQuene.getCustomerquene (). Close (); System.out.println ("¡Cierra la puerta y no recoja a los clientes!"); } System.out.println ("Tiempo de ejecución del sistema:" + (b -a) + "ms"); System.out.println ("Tiempo de inactividad del sistema:" + ((b -a) * Servantnum - ServantThread.getSumServeTime ())); ServantThread.print (); intente {TimeUnit.seconds.sleep (2); } catch (Exception e) {E.PrintStackTrace (); }}}}Lo anterior es una introducción detallada a los principios de Java que implementa la teoría de colas. Espero que sea útil para el aprendizaje de todos.