0

I have this assignment for my Electrical Engineering class we have to simulate the processes of a vaccination center.One thread assigns the patients with some appointment id , and the other thread 'vaccinates' the patients returning a message.The two threads work simultaneously with the patients being asigned an appointment id and the doctors examining them removing them from the list of patients at the same time.The Patient and Doctor class implement the interface runnable so they are ran on seperate threads.The class Appointments is something like a manager which controls when the threads start.

import java.util.ArrayList;
import java.util.Random;

public class Patient implements Runnable {

private static int currentid;

private static ArrayList<Patient>patients = new ArrayList<Patient>();

private String name;    

private int id;

private int sleeptime;

Random r = new Random();







 public Patient() 
 {
 this.sleeptime = r.nextInt(99);    

 patients.add(this);


 }  
 public Patient(String name) 
 {


 this.name  =name;

 this.sleeptime = r.nextInt(99);

 patients.add(this);





  }

  public static ArrayList<Patient>getpatients()
  {
  return patients;

  }
  public String getname() 
  {
  return name;

  }
  public void setname(String name) 
  {
  this.name = name;

  }
  public int getid() 
  {

  return id;
  }
  public void setid(int id) 
  {
  this.id = id;

  }
  public int getsleeptime() 
  {
  return sleeptime;

  }




 public void run()
 {

    
    try 
    {
    
    Thread.sleep(sleeptime);
    
    currentid++;
    
    setid(currentid);
    
    
    
    
    
    
    
    System.out.println("Patient:"+getname()+" with appointment id:"+getid()+" Responded time:"+getsleeptime());

    }
    catch(Exception e) 
    {
    
    
    }
    }

    }

import java.util.ArrayList;
import java.util.Random;

public class Doctor implements Runnable
{
private static int currentid;

private static ArrayList<Doctor>doctors = new ArrayList<Doctor>();  

private String name;

private int id;

private int sleeptime;

Random r = new Random();





  public Doctor() 
  {

  this.sleeptime= r.nextInt(999); 

  currentid++;

  doctors.add(this);


  }
 public Doctor(String name) 
 {
 this.sleeptime= r.nextInt(999); 

 this.name = name;

 currentid++;

 this.id  = currentid;



 doctors.add(this);



 }
 public static ArrayList<Doctor>getdoctors()
 {
 return doctors;

 }
 public String getname() 
 {
 return name;

 }
 public void setname(String name) 
 {
 this.name =name;

 }
 public int getid() 
 {
 return id;

 }
 private int getsleeptime() 
 {
 return sleeptime;

 }
 public void run() 
 {
 try 
 {
    Thread.sleep(sleeptime);
    
    vaccinate(Patient.getpatients());
    
    
    
}
catch(Exception e) 
{
    
    
}
}
private void vaccinate(ArrayList<Patient>patients) 
{





while(patients.size()>=0) 
{
if(patients.get(0).getid()!=0)
{
System.out.println("Doctor:"+getname()+" with id:"+"Vaccinated patient with name:"+patients.get(0).getname()+" with appointment id:"+patients.get(0).getid()+" Response time:"+getsleeptime());

patients.remove(0);
}
else 
{
    System.out.println("Patient("+patients.get(0).getname()+") hasnt received a appointment id yet!");
    
}
}



}

}
import java.util.ArrayList;


 public class Appointments 

 {
 private ArrayList<Patient>patients;

 private ArrayList<Doctor>doctors;



 public Appointments() 
 {

 patients = Patient.getpatients();

 doctors = Doctor.getdoctors();
 }


 public void createAppointments() 
 {
 for(Patient p:patients) 
 {
    Thread t = new Thread(p);
    
    t.start();
    
}

}
public void endAppointments() 
{
for(Doctor d:doctors) 
{
    Thread t = new Thread(d);
    
    t.start();
    
}

}

}

In main I have this code:

Patient p1 = new Patient("Mike Brown");

Patient p2 = new Patient("Scottie Pippen");

Patient p3 = new Patient("Michael Jordan");

Patient p4 = new Patient("LeBron James");

Patient p5 = new Patient("Moses Malone");

Patient p6 = new Patient("A");

Patient p7 = new Patient("B");

Patient p8 = new Patient("C");

Patient p9 = new Patient("D");

Patient p10 = new Patient("E");

Patient p11 = new Patient("F");

Patient p12 = new Patient("G");

Patient p13 = new Patient("H");

Patient p14 = new Patient("I");

Patient p15 = new Patient("J");

Patient p16 = new Patient("K");
    
Patient p17 = new Patient("L");
    
Patient p18 = new Patient("M");
    
Patient p19 = new Patient("N");
    
Patient p20 = new Patient("O");





Doctor d1 = new Doctor("Doctor1");

Doctor d2 = new Doctor("Doctor2");

Appointments app = new Appointments();

app.createAppointments();

app.endAppointments();

Every time I run the program I get a different result as expected.However sometimes I get this at the output:

Patient(J) hasnt received a appointment id yet!
Patient(J) hasnt received a appointment id yet!
Doctor:Doctor2 with id:Vaccinated patient with name:J with appointment id:19 Response time:89
Patient:J with appointment id:19 Responded time:96

which doesnt make any sense to me why does the vaccination message is printed before the appointment id assignment and how do I fix this?

Jun Seo-He
  • 131
  • 5
  • 1
    Without synchronization you're at the mercy of the CPU(s) breaking running/pausing/restarting threads at any instruction it chooses. You need to add the appropriate synchronization so that the the `setId() and println()` are always run together. – kendavidson Jun 10 '21 at 19:03
  • And how do I do that? – Jun Seo-He Jun 10 '21 at 19:13
  • Just google `synchronized method java` or something along those lines. The link @Filip provided below is also full of a bunch of info. If you get your `synchronized{}` code in there and it's still not working, update the question. – kendavidson Jun 11 '21 at 11:42

1 Answers1

1

Your issue is that while patients method run is running, doctors vaccinate starts running and it just happens that vaccinate completes before run so you get this kind of output. This is supposed to happen sometimes and to stop that from happening you can look for solutions like what is mentioned here.

Filip
  • 609
  • 7
  • 18
  • Ok but what I dont get is why "Patient:J with appointment id:19 Responded time:96" isnt printed before "Doctor:Doctor2 with id:Vaccinated patient with name:J with appointment id:19 Response time:89" since from the second message we can see that the patient has received an appointment id so " "Patient:J with appointment id:19 Responded time:96" must be printed before "Doctor:Doctor2 with id:Vaccinated patient with name:J with appointment id:19 Response time:89" – Jun Seo-He Jun 10 '21 at 18:56
  • 1
    It doesn't have to be printed before in this case because one method contains different statements which take different amount of time to complete and they're all separate tasks for processor(s). So when `Patient` thread starts executing before `Doctor` thread, you expect to see output of `Patient` before, but what actually happens is that they're running in parallel and if `Doctor` thread takes less time to execute `print` statement, you will see that statement first. I hope this makes it more clear. – Filip Jun 10 '21 at 19:05