Academic Integrity: tutoring, explanations, and feedback — we don’t complete graded work or submit on a student’s behalf.

Language/Platform This project must target a Unix platform and execute properly

ID: 3740811 • Letter: L

Question

Language/Platform

This project must target a Unix platform and execute properly on our cs1 or csgrads1 Linux server.

The project must be written in C, C++, or Java.

If using C or C++, you must use POSIX pthreads and semaphores.

Doctor’s Office Simulation

This project will simulate a visit to the doctor’s office. It is similar to the “barbershop” example in the textbook.

Overview

The clinic to be simulated has doctors, each of which has their own nurse. Each doctor has an office of his or her own in which to visit patients. Patients will enter the clinic to see a doctor, which should be randomly assigned. Initially, a patient enters the waiting room and waits to register with the receptionist. Once registered, the patient sits in the waiting room until the nurse calls. The receptionist lets the nurse know a patient is waiting. The nurse directs the patient to the doctor’s office and tells the doctor that a patient is waiting. The doctor visits the patient and listens to the patient’s symptoms. The doctor advises the patient on the action to take. The patient then leaves.

Threads

Receptionist – one thread

Doctor – one thread each, maximum of 3 doctors

Nurse – one per doctor thread, identifier of doctor and corresponding nurse should match

Patient – one thread each, up to 30 patients

Inputs

The program should receive the number of doctors and patients as command-line inputs.

Other rules:

A thread should sleep 1 second at each step the thread prints an activity.

All mutual exclusion and coordination must be achieved with semaphores.

A thread may not use sleeping as a means of coordination.

Busy waiting (polling) is not allowed.

Mutual exclusion should be kept to a minimum to allow the most concurrency.

Each thread should only print its own activities. The patient threads prints patient actions and the doctor threads prints doctor actions, etc.

Your output must include the same information and the same set of steps as the sample output.

Output

Each step of each task of each thread should be printed to the screen with identifying numbers so it is clear which threads are involved.

Begin by printing the number of patients, nurses, and doctors in this run.

Thread activity output sample. Your output should contain the same set of steps per thread:

Run with 3 patients, 3 nurses, 3 doctors

Patient 0 enters waiting room, waits for receptionist

Receptionist registers patient 0

Patient 0 leaves receptionist and sits in waiting room

Patient 2 enters waiting room, waits for receptionist

Nurse 0 takes patient 0 to doctor's office

Receptionist registers patient 2

Patient 0 enters doctor 0's office

Patient 2 leaves receptionist and sits in waiting room

Patient 1 enters waiting room, waits for receptionist

Nurse 2 takes patient 2 to doctor's office

Receptionist registers patient 1

Patient 2 enters doctor 2's office

Doctor 0 listens to symptoms from patient 0

Patient 1 leaves receptionist and sits in waiting room

Patient 0 receives advice from doctor 0

Doctor 2 listens to symptoms from patient 2

Patient 2 receives advice from doctor 2

Nurse 1 takes patient 1 to doctor's office

Patient 1 enters doctor 1's office

Doctor 1 listens to symptoms from patient 1

Patient 1 receives advice from doctor 1

Patient 0 leaves

Patient 2 leaves

Patient 1 leaves

.

.

.

Explanation / Answer

Code

import java.util.concurrent.Semaphore;

import java.util.concurrent.locks.Lock;

import java.util.concurrent.locks.ReentrantLock;

import java.util.*;

//Define a class

public class Project2

{

    //Define a class

     class shrdSyncrnztnDta

     {

         //Declare variable

          public Semaphore        lPtnts;  

          //Declare variable     

          public Semaphore        lRcpnst;

          //Declare variable     

          public Semaphore        lNrses;  

          //Declare variable     

          public int                   lMxPtnts;    

         

          //Declare variable

          public int                   lNmPtnts = 0;

         

          //Declare variable

          public Lock                  lMtx;             

         

          //Declare variable

          public int                   lPtId;

         

          //Declare variable

          public Queue<Integer>   lPQue;

         

          //Declare variable

          public Lock                  lMtx2;            

         

          //Declare variable

          public int                   lPRgstd;

         

          //Declare variable

          public int                   lNmNrses;

         

          //Declare variable

          public int                   lNmDctrs;

          //Define constructor

          shrdSyncrnztnDta(int lNm)

          {

              //Assign value

              lPtnts        =    new Semaphore(0);

             

              //Assign value

              lRcpnst   =    new Semaphore(0);

             

              //Assign value

              lNrses             =    new Semaphore(0);

             

              //Assign value

              lMtx          =    new ReentrantLock();

             

              //Assign value

              lMtx2              =    new ReentrantLock();

             

              //Assign value

              lMxPtnts      =    lNm;

             

              //Assign value

              lPQue              =    new LinkedList<Integer>();

             

               //Assign value

              lPRgstd       =    0;

          }

     }

     //Define class

     class Receptionist extends Thread

     {

          //Create instance

          boolean lBsy;

         

          //Create instance

          shrdSyncrnztnDta lSych;

          //Define a constructor

          public Receptionist( shrdSyncrnztnDta s )

          {

              //Assign value

              lBsy = false;

             

              //Assign value

              lSych = s;

          }

          //Define method

          public void run()

          {

              //Loop

              for (int li = 0; li<lSych.lNmPtnts; li++)

              {

                 //Try

                   try

                   {

                       //Call method

                        lSych.lPtnts.acquire();      

                   }

                  

                   //Catch

                   catch (InterruptedException lE){}

                   //Call method

                   lSych.lMtx.lock();                   

                  

                   //Increment

                   lSych.lMxPtnts++;                

                  

                   //Call method

                   lSych.lRcpnst.release();     

                  

                   //Call method

                   lSych.lMtx.unlock();

                   //Try

                   try

                   {

                       //Sleep

                        Thread.sleep(20);

                   }

                  

                   //Catch

                   catch (InterruptedException lE){}         

              }

          }

     }

     //Defien a class

     class Patient extends Thread

     {

         //Declare variable

          int lId;

         

          //Declare variable

          boolean isWaiting;

         

          //Declare variable

          shrdSyncrnztnDta lSych;

          //Define constructor

          public Patient(int lNm, shrdSyncrnztnDta s)

          {

              //Assign value

              lId = lNm;

             

              //Assign value

              isWaiting = false;

             

              //Assign value

              lSych = s;

          }

          //Define method

          public void run()

          {

              //Display message

System.out.println("Patient " + lId + " enters waiting room, waits for lRcpnst.");

             

              //Call method

              lSych.lMtx.lock();                        

              //If condition satisfies

              if (lSych.lMxPtnts > 0)

              {

                   //Decrement

                   --lSych.lMxPtnts;                

                   //Call method

                   lSych.lPtnts.release();              

                   //Call metjod

                   lSych.lMtx.unlock();

                   //Try

                   try

                   {

                       //Call method

                        lSych.lRcpnst.acquire();    

                   }

                  

                   //Catch

                   catch (InterruptedException lE){}

                  

                   //Display message

System.out.println("Receptionist registers patient " + lId);

                  

                   //Try

                   try

                   {

                       //Sleep

                        Thread.sleep(20);

                   }

                  

                   //Catch

                   catch (InterruptedException lE){}

                   //Display message

                   System.out.println("Patient " + lId + "                                        leaves receptionist and sits in waiting room");

                  

                   //Increment

                   lSych.lPRgstd ++;

                  

                   //Call method

                   lSych.lPQue.add(lId);

                  

                   //Assign value

                   isWaiting = true;

              }

             

              //Stop

              Thread.currentThread().stop();

          }

     }

     //Define class

     class Nurse extends Thread

     {

         //Declare variable

          int lId;

         

          //Declare variable

          boolean isBusy;

         

          //Declare variable

          shrdSyncrnztnDta lSych;

          //Define constructor

          public Nurse(int lNm, shrdSyncrnztnDta s)

          {

              //Assign value

              lId = lNm;

             

              //Assign value

              isBusy = false;

             

              //Assign value

              lSych = s;

          }

          //Define method

          public void run()

          {

              //Lock

              lSych.lMtx2.lock();                       

              //If condition satisfies

              if (!lSych.lPQue.isEmpty())

              {

                  //Assign value

                   Integer lPtntId = lSych.lPQue.remove();

                  

                   //Decrement

                   --lSych.lPRgstd;

                   //Call method

                   lSych.lMtx2.unlock();                

                  

                   //Try

                   try

                   {

                       //Sleep

                        Thread.sleep(20);

                   }

                  

                   //Catch

                   catch (InterruptedException lE){}

                   //Display message

System.out.println("Nurse " + lId + " takes patient " + lPtntId + " to doctor's office");

                  

                   //Assign value

                   isBusy = true;

              }

             

              //Call method

              Thread.currentThread().stop();

          }

     }

     //Define method

     public void simulate(int lNmP, int lNmN, int lNmD)

     {

          //Create instance

          shrdSyncrnztnDta lSych = new shrdSyncrnztnDta(15);

         

          //Assign value

          lSych.lNmPtnts = lNmP;

         

          //Assign value

          lSych.lNmNrses = lNmN;

         

          //Assign value

          lSych.lNmDctrs = lNmD;

          //Create instance

          Thread lRcpThrd;

         

          //Assign value

          Thread[] lptThrd = new Thread[lSych.lNmPtnts];

         

          //Assign value

          Thread[] lnrThrd = new Thread[lSych.lNmNrses];

          //Declare variable

          int li;

          //Assign value

          lRcpThrd = new Receptionist(lSych);

         

          //Start

          lRcpThrd.start();

          //Loop

          for (li = 0; li < lSych.lNmPtnts; li++)

          {

             //Try

              try

              {

                  //Sleep

                   Thread.sleep(10);

              }

             

              //Catch

              catch (InterruptedException lE){}

             

              //Create instance

              lptThrd[li] = new Patient(li, lSych);

             

              //Start

              lptThrd[li].start();

    }

    

         //Assign value

          int lj = lSych.lNmPtnts;

          //Loop

          while(lj>0)

          {

              //Loop

         for (li = 0; li < lSych.lNmNrses; li++)

              {

                  //Try

                   try

                    {

                       //Sleep

                        Thread.sleep(10);

                   }

                  

                   //Catch

                   catch (InterruptedException lE){}

                  

                   //Assign value

                   lnrThrd[li] = new Nurse(li, lSych);

                  

                   //Start

                   lnrThrd[li].start();

              }

             

              //Assign value

              lj -= 5;

          }

          //Try

          try

          {

              //Join

              lRcpThrd.join();

          }

         

          //Catch

          catch (InterruptedException lE){}

          //Loop

    for( li = 0; li < lSych.lNmPtnts; ++li )

          {

              //Try

              try

              {

                   //Join

                   lptThrd[li].join();

              }

             

              //Catch

              catch (InterruptedException lE){}

          }

     }

     //Define main

     public static void main(String args[])

     {

         //Declare variables

          int lNmP = 5, lNmN = 5, lNmD = 5;

          //Create instance

          Project2 lClnc;

         

          //Create instance

          lClnc = new Project2();

         

          //Call method

          lClnc.simulate(lNmP, lNmN, lNmD);

     }

}