Accessing HashMap through a singleton
<p>I have a Record class which extends a DoctorRecord class. I want threads to store these records in a hash map which I create as a singleton. My problem is every time a thread adds a record to the hash map and I try to print it's size in the main method (once all the threads have finished executing), I always get a size of 0, as if no modifications were made. However, when I print the size of the map within the method adding the records, it shows the correct size. I'm assuming it's an issue with a pass-by-value mechanic but I can't seem to correct the problem.</p>

<p><strong>Hash Map singleton class:</strong></p>

<pre><code>public class MtlHashMap {

    private static HashMap&lt;Character, ArrayList&lt;Record&gt;&gt; hmMtl = new HashMap&lt;Character, ArrayList&lt;Record&gt;&gt;();

    public static HashMap&lt;Character, ArrayList&lt;Record&gt;&gt; getInstance(){
        return hmMtl;
    }

}
</code></pre>

<p><strong>Thread method being called inside the overridden run() method</strong> (The hash map contains one list for every letter of the alphabet)</p>

<pre><code>public synchronized void createDRecord(String firstName, String lastName, String address, long phone, String specialization, String location){

    System.out.println("Create D Record");
    DoctorRecord d1 = new DoctorRecord(firstName, lastName, address, phone, specialization, location);

        hm = MtlHashMap.getInstance();

    Character ch = lastName.toLowerCase().charAt(0);

    ArrayList&lt;Record&gt; list = (ArrayList&lt;Record&gt;) hm.get(ch);

    if(list == null){
        System.out.println("Create list");
        list = new ArrayList&lt;Record&gt;();
    }

    list.add(d1);
    System.out.println("Size of list " + ch + " is " + list.size());

    hm.put(ch,list);
    System.out.println("Size of " + location + "hash map is " + hm.size());
}
</code></pre>

<p><strong>Main</strong></p>

<pre><code>public class Main {


public static void main(String[] args) throws InterruptedException{

    System.out.println("Main");

    ManagerClient m1 = new ManagerClient("mtl");
    ManagerClient m2 = new ManagerClient("mtl");
    ManagerClient m3 = new ManagerClient("mtl");
    ManagerClient m4 = new ManagerClient("mtl");


    //Create Doctor Record
    m1.run("Joana", "Sam", "272 Montpellier", 1231, "surgeon", "mtl");
    m2.run("Joana", "Sam", "34 Lake", 1231, "surgeon", "mtl");
    m4.run("Joana", "Sam", "34 Lake", 1231, "surgeon", "mtl");

    m1.join();
    m2.join();
    m4.join();

    System.out.println("Size of MTL hash map is: " + MtlHashMap.getInstance().size());
    System.out.println("Size of LVL hash map is: " + LvlHashMap.getInstance().size());
    System.out.println("Size of DDO hash map is: " + DdoHashMap.getInstance().size());
</code></pre>

<p><strong>Manager Client Class</strong></p>

<pre><code>public class ManagerClient extends Thread{ 
private String location;
private String id;
private static int managerIdCounter = 1000; //Maintains unique global IDs


public ManagerClient(String location){
    this.location = location.toLowerCase();
    this.id = location.toLowerCase()+managerIdCounter++;

}

public String getLocation(){
    return (this.location).toLowerCase();
}

public String getmId(){
    return this.id;
}

//Different run method overloads for each of the four methods needed,
//with the appropriate server being called using the locateServer() method


//Default run method never used, but must be overridden anyway
public void run(){
    System.out.println("This should never appear");
}

//Create Doctor Record (5 String and 1 long argument) SYNCHRONIZE THIS FOR SAFE RUNNING
@SuppressWarnings("deprecation")
public synchronized void run(String firstName, String lastName, String address, long phone, String specialization, String location){

    System.out.println("Manager " + this.getmId() + " creates a D record");

    try{
        System.setSecurityManager(new RMISecurityManager());
        String path = "rmi://localhost:2020/"+getLocation();
        ClinicServerInterface server = (ClinicServerInterface)Naming.lookup(path);

        server.createDRecord(firstName, lastName, address, phone, specialization, location);
    }catch(Exception e){
        //e.printStackTrace();
    }

}

//Create Nurse Record (6 String arguments)
public synchronized void run(String firstName, String lastName, String designation, String status, String statusDate){
    System.out.println("Manager " + this.getmId() + " creates a N record");

    try{
        System.setSecurityManager(new RMISecurityManager());
        String path = "rmi://localhost:2020/"+getLocation();
        ClinicServerInterface server = (ClinicServerInterface)Naming.lookup(path);
        server.createNRecord(firstName, lastName, designation, status, statusDate, getLocation());
    }catch(Exception e){
        //e.printStackTrace();
    }       
}

//Get Record Counts (1 int argument)
public void run(int type){
    String location = this.location;

}

//Edit Record (3 String arguments)
public void run(String recrodID, String fieldName, String newValue){
    String location = this.location;
}
</code></pre>

<p>}</p>