HashMap cannot be accessed between threads

classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

HashMap cannot be accessed between threads

Sheldon
Hi, everyone,
     I am developing my own broker for PowerTAC. In debugging, I found that in PortfolioMangerService,  the information in HashMap cannot be accessed in activate() method. I debug this problem using the Sample Broker. The test code I wrote in activate() method is as follows:
     if (380 == timeslotIndex || ((timeSlotCounter > 24)&&(timeSlotCounter % 12 == 0)))
    {    
    // debug the HashMap
        {
        Iterator< Map.Entry<PowerType, HashMap<CustomerInfo, CustomerRecord>> > it = customerProfiles.entrySet().iterator();
     while(it.hasNext())
    {
    Map.Entry<PowerType, HashMap<CustomerInfo, CustomerRecord>> entry =
    (Map.Entry<PowerType, HashMap<CustomerInfo, CustomerRecord>>)it.next();
    PowerType pt = (PowerType)entry.getKey();
    HashMap<CustomerInfo, CustomerRecord> tMap = (HashMap<CustomerInfo, CustomerRecord>)entry.getValue();
    System.out.println("Power type: " + pt.toString() + "\n");
    Iterator< Map.Entry<CustomerInfo, CustomerRecord> > iter = tMap.entrySet().iterator();
    System.out.println("map size: " + tMap.size());
    while(iter.hasNext())
    {
    Map.Entry<CustomerInfo, CustomerRecord> tEntry = (Map.Entry<CustomerInfo, CustomerRecord>)iter.next();
    Object objkey = tEntry.getKey();
    if(objkey == null)
    System.out.println("Error in get key!\n");
    CustomerInfo tCustomer = (CustomerInfo)objkey;
    Object objval = tEntry.getValue();
    CustomerRecord tRecord = (CustomerRecord)objval;
    //CustomerInfo tCustomer = tEntry.getKey();
    //CustomerRecord tRecord = tEntry.getValue();
    if(tCustomer == null)
    System.out.println("Error! null customer\n");
    if(tRecord == null)
    System.out.println("Error! null record\n");
    System.out.println("Key: " + tCustomer.getName() + "   Value: " + tRecord.subscribedPopulation);
        }
    }
        }   Here is the output bug:

   Can anyone offer some kind help? Thanks a lot!
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: HashMap cannot be accessed between threads

gbuijs
Hi,

A couple of things :

HashMap aren't thread safe, meaning that it will get corrupted if it gets updated by different threads.
The thread safe version of HashMap is ConcurrentHashMap.

But i'm not sure that it's actually a problem of thread safety.
At the end of your code you check if tCustomer equals null, which it does.
But after that you try to print tCustomer.getName(), which throws the NullPointerException.

First make sure that the maps are properly populated.

Cheers,

Govert
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: HashMap cannot be accessed between threads

Sheldon
Hi, Govert
     Thanks for your suggestions.
     First it is sure that the HashMap is well populated in the beginning. I tested the HashMap in the createInitialTariffs (), and it is right. But after handling the message function: handleMessage(TariffTransaction ttx), the HashMap cannot be accessed.
     I used ConcurrentHashMap instead. Here is the test results:
     In createInitialTariffs (), it is right.
     
     after several timeslots, the broker must have run several times of handleMessage(TariffTransaction ttx), the error occurs in the map in improveTariffs()
     
     There are two problems in the map
     1. Interruptible_consumption includes thermal_storage_consumption, Consumption includes Interruptible_consumption.
     2. the field of Value should not be zero, but the population of the subscribed customers.
     I just tested the code on SampleBroker, with no other modifications. I am curious why the map does not work between threads. Or do I have to change to other data structure, like vector<>, but that would be unconvenient.
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: HashMap cannot be accessed between threads

Sheldon
In fact, the map for Interruptible_consumption and Consumption go wrong randomly in each test, but the maps for other consumers are right.
I wonder if it is concerned to the environment where I test the sample broker. I tested the sample broker in the simulation environment in my local machine.
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: HashMap cannot be accessed between threads

grampajohn
Administrator
In reply to this post by gbuijs
gbuijs wrote
HashMap aren't thread safe, meaning that it will get corrupted if it gets updated by different threads.
The thread safe version of HashMap is ConcurrentHashMap.
It is not necessary to use a ConcurrentHashMap. In the sample broker MarketManagerService and PortfolioManagerService, all the handleMessage() methods (except the one for CustomerBootstrapData) are synchronized, and the activate() methods are synchronized. Those are the only entry points after initialization. Probably the handler for CustomerBootstrapData should also be synchronized; I considered that to be part of initialization, but I am not entirely confident that  the lack of synchronization on that method won't cause a problem.

Cheers -

John
Loading...