Red de conocimiento informático - Consumibles informáticos - Simulación de operación bancaria Diseñe una aplicación Java para simular el fenómeno de los clientes depositando y retirando dinero del banco. Gracias

Simulación de operación bancaria Diseñe una aplicación Java para simular el fenómeno de los clientes depositando y retirando dinero del banco. Gracias

Los modelos de productor y consumidor utilizados tienen las siguientes características:

(1) Los múltiples buffers en este experimento no son circulares y no requieren acceso secuencial. El productor puede colocar el producto en uno de los buffers actualmente vacíos.

(2) Los consumidores sólo consumen productos de productores designados.

(3) Todos los requisitos de producción y consumo se especifican en el archivo de caso de prueba. Solo cuando los datos en el búfer compartido cumplen con todos sus requisitos de consumo, el búfer compartido se puede utilizar como espacio libre para nuevos. productores a utilizar.

(4) En este experimento, al asignar reservas a los productores, cada productor debe ser mutuamente excluyente. Después de eso, las actividades de producción específicas de cada productor pueden ser concurrentes. Los consumidores solo necesitan ser mutuamente excluyentes cuando consumen el mismo producto. Al mismo tiempo, deben determinar si el objeto de consumo se ha consumido y liquidar el producto al final del proceso de consumo.

Entidades utilizadas por Windows para implementar la sincronización y exclusión mutua. En Windows, los objetos de sincronización comunes incluyen: semáforo, exclusión mutua, sección crítica, evento, etc. Los primeros tres se utilizan en este programa. El uso de estos objetos se divide en tres pasos: uno es la creación o inicialización: luego se solicita el objeto de sincronización y luego se ingresa a la sección crítica. Este paso corresponde al bloqueo

del mutex; Objeto de sincronización, que corresponde al desbloqueo del mutex. Estos objetos de sincronización se crean en un hilo y se pueden usar en otros hilos

para lograr la exclusión mutua de sincronización. Por supuesto, el método para utilizar estos objetos de sincronización para lograr la sincronización entre procesos es similar.

1. Utilice primitivas de operación de bloqueo para lograr la exclusión mutua

Para resolver el problema de la exclusión mutua de procesos que ingresan a secciones críticas, se puede configurar un bloqueo para cada tipo de sección crítica. El bloqueo tiene dos estados: abierto y. cerrado. El proceso se ejecuta. La operación del programa de la sección crítica se realiza de acuerdo a los siguientes pasos:

①Cerrar la cerradura. Primero verifique el estado de la cerradura, si está cerrada espere a que se abra; si ya está abierta, ciérrela y continúe con el paso ②.

②Ejecutar el programa de la sección crítica.

③Desbloquear. Abra la cerradura y salga de la sección crítica.

2. Semáforos y primitivas de operación WAIT, SIGNAL

El sistema puede determinar el valor inicial del semáforo en función de las condiciones de los recursos y las necesidades de uso. En condiciones iniciales, el elemento del puntero del semáforo se puede establecer en 0, lo que indica que la cola está vacía. El valor de un semáforo es variable durante su uso, pero sólo puede cambiarse mediante operaciones WAIT y SIGNAL. Supongamos que el semáforo es S, la operación de ESPERA en S se registra como ESPERA (S) y la operación de SEÑAL en él se registra como SEÑAL (S).

ESPERAR (S): Ejecuta las siguientes dos acciones en secuencia:

①El valor del semáforo se reduce en 1, es decir, S=S-1;

②Si S≥0, entonces el proceso continúa ejecutándose;

Si S(0), el estado del proceso se establece en el estado de bloqueo, el WAITCB correspondiente se conecta al final del cola de semáforo y el procesador se abandona, espere (hasta que otros procesos realicen operaciones de SEÑAL en S y lo liberen)

SEÑAL (S): realice las siguientes dos acciones en secuencia

①El valor de S aumenta en 1. , es decir, S=S+1;

② Si ​​S) 0, el proceso continúa ejecutándose

Si S (0, entonces; libere el primer PCB en la cola del semáforo (es decir, la señal El proceso correspondiente al PCB señalado por el elemento del puntero de cantidad (cambia el estado de bloqueo al estado listo), y el proceso que realiza la operación SEÑAL continúa ejecutándose.

En la implementación específica, tenga en cuenta que las operaciones WAIT y SIGNAL deben tratarse como Una implementación general no permite la ejecución dividida o entrelazada. En otras palabras, las operaciones WAIT y SIGNAL parecen corresponder cada una a una instrucción y. debe ejecutarse continuamente, de lo contrario causará confusión en términos de conceptos físicos. Cuando se habla del semáforo S), el valor S representa la cantidad de recursos disponibles.

Realizar una operación WAIT significa solicitar la asignación de un recurso unitario, por lo que el valor S se reduce en 1 cuando S <0, significa que no hay recursos disponibles y el solicitante debe esperar a que otros procesos liberen este tipo de recurso; antes de que pueda seguir funcionando. Entonces se va a alinear. Realizar una operación de SEÑAL significa liberar un recurso unitario, por lo que el valor S aumenta en 1; si S (0), significa que algunos procesos están esperando el recurso, por lo que el proceso al principio de la cola debe despertarse. El proceso que libera el recurso siempre se puede ejecutar.

--------------

/**

* Productor

*

*/

El productor de clase pública implementa Runnable{

mutex de semáforo privado, completo, vacío;

buf de búfer privado;

p>

Nombre de cadena;

Productor público (Nombre de cadena, Semáforo mutex, Semáforo lleno, Semáforo vacío, Buffer buf){

this.mutex = mutex;

this.full = lleno;

this.empty = vacío;

this.buf = buf;

this.name = nombre;

}

public void run(){

while(true){

vacío.p();

mutex.p();

System.out.println(name+" inserta un nuevo producto en "+buf.nextEmptyIndex);

buf.nextEmptyIndex = (buf. nextEmptyIndex +1)%buf.size;

mutex.v();

full.v()

prueba {

Thread.sleep(1000);

} catch (InterruptedException e) {

e.printStackTrace();

}

}

}

}

---------------

/**< / p>

* Consumidor

*

*/

clase pública El cliente implementa Runnable{

mutex de semáforo privado, completo ,vacío;

buf de búfer privado;

nombre de cadena;

cliente público (nombre de cadena, exclusión mutua de semáforo, semáforo lleno, semáforo vacío, buf de búfer){

this.mutex = mutex;

this.full = lleno;

this.empty = vacío;

this.buf = buf;

this.name = nombre;

}

public void run(){

while(true){

full.p();

mutex.p();

System.out.println(name+" obtiene un producto de "+buf.nextFullIndex);

buf.nex

tFullIndex = (buf.nextFullIndex+1)%buf.size;

mutex.v();

vacío.v()

prueba {

Thread.sleep(1000);

} catch (InterruptedException e) {

e.printStackTrace();

}

}

}

}

--------------------- ----

/**

* Buffer

*

*/

buffer de clase pública {

Búfer público(int size,int nextEmpty,int nextFull){

this.nextEmptyIndex = nextEmpty;

this.nextFullIndex = nextFull;

p>

this.size = tamaño;

}

public int tamaño

public int nextEmptyIndex;

public int nextFullIndex;

}

-----------------

/**

* Esta clase se utiliza para simular un semáforo

*

*/

clase pública Semaphore{

private int semValue;< / p>

Semáforo público (int semValue){

this.semValue = semValue;

}

público sincronizado void p(){

semValue--;

if(semValue<0){

prueba {

this.wait();

} captura (InterruptedException e) {

e.printStackTrace();

}

}

}

vacío sincronizado público v(){

semValue++;

if(semValue<=0){

this.notify();

}

}

}

---------------------- - -

Prueba de clase pública extiende el hilo

{

public static void main(String[] args)

{

Buffer bf=nuevo Buffer(10,0,0);

Semáforo mutex=nuevo Semáforo(1);

Semáforo completo=nuevo Semáforo(0);

p>

Semáforo vacío=nuevo Semáforo

(10);

//nuevo Hilo(nuevo Productor("p001",mutex,full,empty,bf)).start();

Productor p=nuevo Productor( "p001",mutex,full,empty,bf);

nuevo hilo(nuevo Productor("p002",mutex,full,empty,bf)).start();

nuevo Hilo(nuevo Productor("p003",mutex,full,empty,bf)).start();

nuevo Hilo(nuevo Productor("p004",mutex,full,empty,bf) ).start();

nuevo hilo(nuevo Productor("p005",mutex,full,empty,bf)).start();

probar{

dormir(3000);

}

catch(Excepción ex)

{

ex.printStackTrace();

}

nuevo hilo(nuevo cliente("c001",mutex,full,empty,bf)).start();

nuevo hilo(nuevo cliente ("c002",mutex,full,empty,bf)).start();

new Thread(new Customer("c003",mutex,full,empty,bf)).start();

nuevo Hilo(nuevo Cliente("c004",mutex,full,empty,bf)).start();

nuevo Hilo(nuevo Cliente("c005",mutex, lleno,vacío,bf)).start();

}

}

--------------- --------------------------