File APIs for Java Developers
Manipulate DOC, XLS, PPT, PDF and many others from your application.
http://aspose.com/file-tools
The moose likes Threads and Synchronization and the fly likes Sync block and variable references Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Java » Threads and Synchronization
Bookmark "Sync block and variable references" Watch "Sync block and variable references" New topic
Author

Sync block and variable references

Jerome Mrozakski
Greenhorn

Joined: Nov 17, 2010
Posts: 2
In a synchronized block, is the target object referred to by its address or by what it points at? For example,



Suppose there are two simultaneous server requests that enter myMethod(). Will they serialize on someString because they recognize that it points at some global value? Or will they fail to serialize because someString is declared locally, and the two threads never see the other thread's version of someString?

In this I'm trying to be subtle. If I use a global object then all of my web site visitors serialize through that object. If I could serialize just the double-clicks, or the multiple uses/abuses of a user of my single web page, then each web site user would have their own synchronizing variable.

I'm satisfied with the global sync object, as long as my sync section is short enough. My colleagues think I should find that magic value that provides one sync object per logged-in user.

TIA,
Jerome.
Steve Luke
Bartender

Joined: Jan 28, 2003
Posts: 4174
    
  21

You sync on the instance of the Object itself, not the reference or variable. So if all your users see the same String instance, they will all see be locking on the same object. Since Strings are held in a special cache, there is a good chance (though not absolutely sure) that they all use the same String Object instance.

If you want one lockable Object per user, the Session object is a good place to start. Each user has their own session - so it seems relatively natural to use that as a source for locks.


Steve
Jelle Klap
Bartender

Joined: Mar 10, 2008
Posts: 1760
    
    7

Steve Luke wrote:If you want one lockable Object per user, the Session object is a good place to start. Each user has their own session - so it seems relatively natural to use that as a source for locks.


I guess it's pretty safe to synchronize on the HttpSession instance itself, though I'm not sure that is guaranteed to work in every single servlet container / application server out there. I do know that SpringMVC Controllers provides a mechanism that allows you to serialize access to the HttpSession, though I'm not sure how exactly that is implemented under the covers. Though that mechanism is related to a specialized HttpSessionListener implementation, so it's a pretty safe bet that the process is a bit more involved than simply synchronizing on the HttpSession instance.

Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.
Jerome Mrozakski
Greenhorn

Joined: Nov 17, 2010
Posts: 2
I've been unsure about what gets locked. Steve says that if I pass in a session reference that I still lock, because what is pointed at, not the pointer, is in the locking table. This would mean that this code:



would work because what is locked is what session points at, whatever was returned from getSessionSomehow().

So, does the locking object have to be something global? Or merely resolve to the same something in a Great Object Locator? Suppose getSessionSomehow() created a new Object and passed it back. That isn't a global (class visibility) object.

If a global object is required, I'm sure I can put into the session some user-specific String, such as "Jerome's locking string", so that when Steve logs in he doesn't refer to Jerome's locks.

Comments?
Steve Luke
Bartender

Joined: Jan 28, 2003
Posts: 4174
    
  21

The Object has to exist in the same scope as the level you want to synchronize on. If the 'getSessionSomehow()' method created a new Object each time, then it would not be worth synchronizing on - because each Object has its own Lock, and so no synchronization would happen.

It doesn't have to be global - all users don't need access to the same instance. But it does have to have the same scope as the necessity to synchronize (ie in your case it would need to be scoped to the user, or session).

The problem with the session being serializable is real and needs to be considered. But when you consider it - synchronizing on any Object that is put into the session also is an issue - because if the session is serialized then so to are the Objects in it. Assuming that Strings will not be affected is also a mistake since there are cases where Strings don't get drawn from the String pool - and so you could get multiple instances of the String - especially if the String was serialized. To get around this you have to understand when the session will get serialized. My understanding is there are two cases:
1) The session has not been accessed in a while and there are memory constraints, so the session is serialized to remove it from memory, then deserialized when it comes out.
2) The application is hosted on a cluster and a single user can have requests hosted on multiple servers. The session gets serialized to a database so it is available to all servers.

You have to look at your situation and see if those use-cases affect your application. If the session is serialized because of inactivity, do you need to worry about synchronizing on different instances? Perhaps not - the need to synchronize between requests indicate that the requests are happening close enough in time as to interfere with each other. If there are two different session objects because of serialization then the requests probably can't have been made close enough together to require synching between them.

If you have a cluster then you can not use any Java object to do synchronization, and you need to worry about synchronizing using some other scheme (such as DB tables, Files in a file system, or Sockets). You also might want to consider why you need synchronizing across servers - or to see if it is better to force user request - server consistency (ie all requests from one user goes to the same server) to try and avoid this situation.
Alex Hurtt
Ranch Hand

Joined: Oct 26, 2010
Posts: 98
Are you trying to enforce transactional idempotence using synchronization? Because that's the impression I got when you said:

In this I'm trying to be subtle. If I use a global object then all of my web site visitors serialize through that object. If I could serialize just the double-clicks, or the multiple uses/abuses of a user of my single web page, then each web site user would have their own synchronizing variable.


If so, there are better existing ways to do it without having to resort to creating a performance bottleneck for all your users by trying to lock on some 'global' Object instance.
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: Sync block and variable references