java - Nested synchronized blocks on interned Strings -
The title seems to have many problems in front of me: this is my special case:
This is a travel ticket There is a limited amount of tickets in each route, and therefore, buying last tickets for the given route should not be accessible to two people (a standard scenario). However, there is a "return ticket" option. Therefore, I am using the unique route ID (database-provided) to do the following:
synchronize (bothRoutesUniqueString.intern ()) { Synchronized (routeId.intern ()) {if (returnRouteId! = Null) {synchronize (returnRouteId.intern ()) {return doPurchase (selectedRoute, selectedReturnRoute); }} Return doPurchase (selected route, selected ReturnRoute); }}
The thread is only two inner synchronized
blocks to close there if this special route ticket is being purchased by two people on the same time No, if the tickets are purchased at the same time for two different routes. The second synchronization is that if this is due to the fact, then anybody can try to buy retire route at the same time as the outbound route.
The external maximum synchronized
is the account for the block scenario, when two people buy the same combination of tickets, are reversed. For example, an order would be from London-Manchester, and other orders Manchester-London. If there is no external synchronized block, then this situation can reach a stalemate.
( doPurchase ()
method either returns an ticket
, or throws an exception, if no more tickets are available)
Now, I have complete information that this is a very strange solution, but if it works, as expected, then it gives: / P>
- The entire complex 10 lines to handle landscapes (and with reasonable observations, it will not be difficult to understand)
- No unnecessary locking - everything else VAL happens when it is to block.
- Database agnosticism
I know that such scenarios are controlled by pessimistic or optimistic database locks, and since I am using hibernate , It will not be difficult to apply either.
I think horizontal scaling can be obtained from the above code using VM clustering. According to this, this single-node allows the multithreaded app to be converted to a multi-node, and:
calls terracotta strings. Intern () and these clearly reference reference for the intersection string Guarantees. After pointing the canonical value of all references to an internal string object, the parallelism referenced will work as expected for distributed applications.
So, now on the questions themselves:
- Are you seeing any flaw on the above code (different from its strange)?
- Is there an applicable class from the
java.util.concurrent
API to help in this scenario? - Why would locking a database be better than this?
Update: Since most answers are related to AumMorrier error
, I have created a benchmark for intern ()
, and The memory has not been eaten. Perhaps the wire table is being cleaned, but it will not make any difference to my case, because I should have the object equal in the race conditions, and most recent strings should not be at the clearing point:
println (Runtime.getRuntime () freeMemory ().); For (Int i = 0; I <10000000; i ++) {String.valueOf (i). International (); } System.out.println (Runtime.getRuntime (.) FreeMemory ());
The PS Environment is JRE 1.6
Internal is a modest expensive operation , And there is a small chance that it will chew it to increase the CPU time more than possible option but, of course, I can not see it much more in the time of the wall compared to querying a database. The only such scenario where I could imagine a DB-based implementation to win, if you have too many formulas in parallel, you will be happy to do some work to DB, so your CPU will wait, but do not grind
For an acceptable limited range of applications you want, your solution looks great for me.
Comments
Post a Comment