• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

Multi-threads access singleton

 
Greenhorn
Posts: 22
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Dear all,

I have a problem. If a singleton contains a Hashmap variable and it is accessed by different threads. Different threads put or get value to/from the Hashmap through the singleton reference. At some time, a thread cannot get a value from the Hashmap although this value is stored to Hashmap with the key before. Below are the sources :

public class DataMap
{
private static DataMap uniqueInstance = new DataMap ();
private HashMap htCache = null

private DataMap() {
htCache = new HashMap();
}

public static Singleton getInstance() {
return uniqueInstance;
}

public Object get(Object key) {
return htCache.get(key);
}

public void put(Object key, Object value) {
return htCache.put(key, value);
}
}

public class TestThread extends Thread {

public void run() {
....
if (true)
DataMap.getInstance().put(key, value);
else
Object obj = DataMap.getInstance().get(key);
....
}
}

A thread T1 will put a value with a key to HashMap in the Singleton DataMap and then another thread (or the same thread) T2 will get the value by using the key after several minutes. T2 may not get a value from HashMap. T1 and T2 threads are not in the same ThreadGroup. So should I add an object lock to synchronize the method "get" and
"put"? Anyone know why and please kindly help.

Thanks.
 
Ranch Hand
Posts: 1078
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Your question is very confusing. What are you trying to do?


A thread T1 will put a value with a key to HashMap in the Singleton DataMap and then another thread (or the same thread) T2 will get the value by using the key after several minutes. T2 may not get a value from HashMap.



What does that mean? If it's the same thread it's going to get a value. If it's a different thread and executes after the thread that put the value then it will get a value. If it's a different thread and executes while the other thread is putting the value then you're going to get undetermined behavior.


T1 and T2 threads are not in the same ThreadGroup.



The ThreadGroup has nothing to do with whether or not they can access the DataMap.


So should I add an object lock to synchronize the method "get" and "put"?



If you don't want DataMap to be accessed concurrently then I would mark both the put and get methods as synchronized or synchronize internally. Which you choose depends on the use and whether or not you need to be able to externally synchronize a series of invocations.
 
ricky wong
Greenhorn
Posts: 22
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
The running order to access the Singleton DataMap by different threads in the program within a short time is :

T1 puts value V1 with key K1 to DataMap.
T2 puts value V2 with key K2 to DataMap.
T3 puts value V3 with key K3 to DataMap.
T4 puts value V4 with key K4 to DataMap.
:
:
Ta gets value from DataMap with Key K1.
Tb gets value from DataMap with Key K2.
Tc gets value from DataMap with Key K3.
Td gets value from DataMap with Key K4.
:
:

I found that Ta could not get value from DataMap with Key 1 although T1 has been run and attempted to put value V1 with Key K1 to DataMap (according to my program log).

I guess the cause may be due to T1 have not put the value to DataMap successfully and Ta attempts to get value from DataMap. Do anyone know how to control the order? Use a queue??

Thanks.
 
Ranch Hand
Posts: 84
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Ricky,

As Ken mentioned, to be sure that T1 is not in the middle of the put when Ta tried the get with the same key, you would need to synchronize the get() and put() methods, like this:




It sounds like, though, from your last post, you are actually asking about how to be sure the put happens before the get (instead of in the reverse order). The synchronized methods will ensure that whichever method call is started first will finish before the other starts, but won't guarantee anything about the order of the two.

If you're interested in having one thread wait to do its task until it has been notify-ed that another thread has finished its task, look at Object.wait() and Object.notify().

Each "writer" thread would do its "put()", then call someObject.notify(). Each "reader" thread would call someObject.wait(), which would block until the notify() was called by the other thread.

It's been a while since I've had to mess around with wait() and notify(), but I think I remember there's a "gotcha" here, in that you have to be sure (somehow) that the "writer" thread doesn't start and finish (and call notify()) before the "reader" thread can call wait()... or else, it'll be waiting for a notify() that will never come, and hang forever.

Can someone who is more current on this confirm or deny that, and recommend a solution? Seems like catch-22 to me, at the moment: how do you guarantee the order of operations (waits and notifies) between threads, so that you know the mechanism for guaranteeing the order of operations (writes and reads) will work?

Anyway: once that's answered, the Object in question, in your case, might be the hash Key objects? But this depends on the two threads actually using the same instance of the Key object, not just two separate instances which are equivalent under the "equals()" method.... which is more strict than is usually required by HashMap. (Maybe in your app, there is some better candidate for the object to use for the wait() and notify() - in the snippet you gave the keys were the only obvious choice.)


And here are a couple of smart-aleck answers, in case you don't care for the one above:

  • your "put()" method is declared void, but returning Object
  • your "getInstance()" method is declared to return Singleton, but is returning a DataMap, which is not declared to implement or extend Singleton.

  • Neither of those are going to help get the desired results


    Hope some (any) of this has helped....

    -- Jon
     
    author
    Posts: 14112
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    If just synchronizing put and get doesn't solve your problem, you should google for the "Producer Consumer" pattern.
     
    Ken Blair
    Ranch Hand
    Posts: 1078
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator

    Originally posted by Ilja Preuss:
    If just synchronizing put and get doesn't solve your problem, you should google for the "Producer Consumer" pattern.



    Aye, I was just wondering if this is what they're trying to accomplish or not. Looks more like an attempt to create a thread-safe HashMap more than anything else.
     
    Ken Blair
    Ranch Hand
    Posts: 1078
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator

    Originally posted by Jon Egan:
    Can someone who is more current on this confirm or deny that, and recommend a solution? Seems like catch-22 to me, at the moment: how do you guarantee the order of operations (waits and notifies) between threads, so that you know the mechanism for guaranteeing the order of operations (writes and reads) will work?



    Since it sounds like you're talking about the Producer/Consumer pattern then AFAIK as long as the consumer checks for availability before waiting it should be fine.
    reply
      Bookmark Topic Watch Topic
    • New Topic