1

I am using JCS for caching in my application.Recently some errors are occuring where concurrent access to data in the cache results in null value i.e one thread writes to the cache and one thread reads to the cache.I want to know whether JCS inherently supports thread safe implementations when writing and reading from the cache. I also want to know how to make my implementation thread safe.Because I have multiple classes writing to the cache,say PutData which implements Runnable is used for writing to the cache and GetData which also implements Runnable for reading from the cache,so making the method synchronized has no meaning and also making them atomic also is not meaningful since the data is not shared among the classes and I pass around the data object to the individual classes.BTW I am using a POJO serialiazed class. Is there anyway to overcome this,or do I have to change my implementation in such a way that it forcefully completes writing and then reading,which is foolish I think.

This is more of like a producer-consumer problem except in the fact that my consumer thread here is not consuming data,but just reading data. So synchronizing does guarantee that only one thread writes to the cache,but that does not solve my problem because the other thread accesses objects of different key.

Expecting your answers, Thanks, Madhu.

Madusudanan
  • 1,017
  • 1
  • 15
  • 36

2 Answers2

5

Recently I started using JCS and I had the problem "Is JCS thread safe?". Well I had a look at the source code and found that the implementation has considered about thread safety.

JCS.getInstance(String region) does always return the same CompositeCache object per region key, wrapped in a new JCS object.In other words, reference of the one an only CompositeCache object is kept in a newly created wrapper JCS object. When we call methods like JCS.get(), JCS.put(), JCS.remove() etc. it will always ended up in invoking a method of the one an only CompositeCache object. So, it is singleton.

Importantly, CompositeCache object has synchronized methods for its write operations (put remove etc.) and in the inner implementation Hashtable objects have been used, which are also thread safe. So I think the JCS has taken care of thread safety at atomic levels.

What Thomas has mentioned above is true. If the cache object was synchronized, then a concurrency issue should have been avoided, which seems to be not the case as mentioned above, may be the issue is something else not really concurrency.

However, I just wanted to share the fact that, one should not plan to use the JCS by gaining an object level lock as discussed above, as the implementation seems to be thread safe, and we should let the concurrency to be handled at more atomic levels, looking for better performance.

0

I don't know JCS but you can synchronize on objects, so you might want to synchronize on the cache object.

Someting like this:

public void putToCache(...) { 
  synchronized (cache) { //cache is your actual cache instance here
   //put to cache here
  }
} 
Thomas
  • 87,414
  • 12
  • 119
  • 157
  • @MadhuSudhan So you did put the synchronized block _into_ the methods and synchronized on the _same_ cache instance? – Thomas Dec 12 '11 at 13:05
  • I have already tried this,since I am using the runnable interface,I have tried as public synchronized void run().But it has no effect.I also used synchronized on the calling method,still no effect.Is there any interface which I can implement such as a SingleThreadModel in a servlet. – Madusudanan Dec 12 '11 at 13:05
  • @MadhuSudhan See my edited answer. You don't synchronize the method itself but add a `synchronized` block _inside_ the method and synchronize on the _cache instance_ not on any non-shared object. – Thomas Dec 12 '11 at 13:07
  • I'll put my code here(Sorry about the alignment) public class PutData implements Runnable { JCSBean data; JCS cache; public PutData(JCSBean data,JCS cache) { this.data=data; this.cache=cache; } public synchronized void run() { try { cache.put( data.getId(), data ); } catch( CacheException e ) { System.out.println("Error adding items to cache"); } } } Where do I synchronize here,the PutData thread is called each time whenever data is needed to be put to the cache. – Madusudanan Dec 12 '11 at 13:14
  • @MadhuSudhan Please read my answers and comments again: don't synchronize the methods, synchronize _on the cache instance_ (which is done using a `synchronized` block _inside_ the methods). – Thomas Dec 12 '11 at 13:18
  • Thanks.It worked partially,but it doesnt work when I put a stream of data in a single go such as in a for loop. – Madusudanan Dec 14 '11 at 10:39