0

I read that in Java EE a Web Service will spawn a thread for every request, so I don't have to thread blocking operations (e.g. database queries) myself.

How would I properly access a shared resource from such thread-dispatched method?

e.g. if I have a SessionManager which contains a map of User objects and a loginUser() method to allow logins outside of a JSF context, how would I prevent race conditions? Do I just use mutexes, or does JavaEE provide a solution to this problem?

Arjan Tijms
  • 37,782
  • 12
  • 108
  • 140
Zyl
  • 2,690
  • 2
  • 22
  • 27

2 Answers2

1

If you need to use Map you can use Concuurent HashMap.. Java won't deal with something you want to create manuallylike webserver that will hold key value pairs of users and something like sessionId after login, Usually the Server can do it..

Anyway this is not a problem.. This ConcurrentHashMap is perfect for those situations, It Thread-Safe, And it is higher performance than HashTable(They work diffrently)

HashTable lock the Map ConcurrentHashMap lock evrey item by himself.. So 2 threads can use the map together if they are not touching the same nodes..

You should read this: http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ConcurrentHashMap.html

Hope that helps

Aviad
  • 1,539
  • 1
  • 9
  • 24
  • We want to allow logons from a native Android App, so we cannot use @ SessionScoped @ ManagedBeans. – Zyl May 29 '14 at 13:23
  • Got you.. You can generate your own sessionId, Once the user is doing login you save userId with your SessionId in this map. In case the user logout you remove from map... And in case the user closed the application not in proper way, You can set timer and check if the last action has been maid befoer 15 minutes so you automatically remove this user from login map – Aviad May 29 '14 at 13:41
  • 1
    Please remmember that if you have some clustered enviorment.. This won't be the best solution, You need to read a little bit about redis..They provide cache capablities.. Check this link http://redis.io/topics/cluster-tutorial – Aviad May 29 '14 at 13:42
  • I understand, but it won't be that big of a system. Thanks. – Zyl May 29 '14 at 15:41
1

Java EE doesn't provide you with any solution for resource contention over your own resources; but Java does.

For your case, using a ConcurrentHashMap may solve most of your problems. A ConcurrentHashMap will protect you against cases in which two threads update the Map in exactly the same time (which, in a HashMap, is likely to throw an exception). It offers you the same methods from the Map interface as HashMap, plus a few useful methods from the ConcurrentMap interface (such as replace and putIfAbsent). For most needs, this option is sufficient.

Having said that, sometimes, you might need to use the synchronized keyword even if you're using a ConcurrentHashMap. For example, consider a case when you'd like to put two items into the Map, but it's extremely important to you that, while the current thread is issuing the two puts, no other thread will get or put from the Map. In other words, ConcurrentHashMap only isolates access for each call individually; for cases when you need the isolation to span multiple calls, use synchronized.

EDIT following @Arjan's comment: if you're using JavaEE 6.0 onwards, you can use @Singleton in combination with @Lock to achieve a similar effect.

Isaac
  • 16,458
  • 5
  • 57
  • 81
  • 1
    >Java EE doesn't provide you with any solution - Uhm, what about @Singleton and @Lock? See http://docs.oracle.com/javaee/6/api/javax/ejb/Lock.html – Arjan Tijms May 29 '14 at 20:22