This week's book giveaway is in the Servlets forum.
We're giving away four copies of Murach's Java Servlets and JSP and have Joel Murach on-line!
See this thread for details.
The moose likes Threads and Synchronization and the fly likes How to make a class thread safe Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Murach's Java Servlets and JSP this week in the Servlets forum!
JavaRanch » Java Forums » Java » Threads and Synchronization
Bookmark "How to make a class thread safe" Watch "How to make a class thread safe" New topic
Author

How to make a class thread safe

Swapnil Shroff
Ranch Hand

Joined: Mar 07, 2006
Posts: 58
I have a following class



What is the least costly way to make this class thread safe

Thanks


SCJP 5, SCDJWS<br /> <br />It's amazing how premature optimisation is both seductive and destructive; even when you know
Henry Wong
author
Sheriff

Joined: Sep 28, 2004
Posts: 18509
    
  40

Since both method calls are atomic operations, I would say that the "least costly" method is to just change the variable to volatile. Like such...



Henry


Books: Java Threads, 3rd Edition, Jini in a Nutshell, and Java Gems (contributor)
Henry Wong
author
Sheriff

Joined: Sep 28, 2004
Posts: 18509
    
  40

The followup question is, of course, what if *not* all of the methods are atomic operations? For example...



Then you have two choices. You can synchronize the access like so...



Or you can use optimistic locking like so...



Now, as to which is faster, it would depend on how they are used. But in the general case, the second should be faster.

Henry
Ernest Friedman-Hill
author and iconoclast
Marshal

Joined: Jul 08, 2003
Posts: 24183
    
  34

Originally posted by Henry Wong:

Now, as to which is faster, it would depend on how they are used. But in the general case, the second should be faster.


Interesting! Not contradicting you at all, Henry, I'm just not as familiar with java.util.concurrent as I should be. Can you cite evidence for this claim? I didn't think any of the java.util.concurrent stuff used native magic; if so, it's going to be using synchronization under the hood, so I would guess the performance would be a wash (if it's not slower due to the one extra indirection, that is.) You're the expert here, though, so I'm looking forward to your reply.


[Jess in Action][AskingGoodQuestions]
Henry Wong
author
Sheriff

Joined: Sep 28, 2004
Posts: 18509
    
  40

Originally posted by Ernest Friedman-Hill:

Interesting! Not contradicting you at all, Henry, I'm just not as familiar with java.util.concurrent as I should be. Can you cite evidence for this claim? I didn't think any of the java.util.concurrent stuff used native magic; if so, it's going to be using synchronization under the hood, so I would guess the performance would be a wash (if it's not slower due to the one extra indirection, that is.) You're the expert here, though, so I'm looking forward to your reply.


Yup, it does accomplish this feat by using "native magic"...

We did the testing a few years ago, for the update of the book. And what we saw was...

For simple operations, where the lock was not contended, there was very little improvement. For contended locks, (but small number of threads) the improvement was very measureable. As the number of threads increased, the optimistic locking collisions increased -- it was still better than synchronization, but less so.

Now, by "general case", I have to qualify it to, "within the limits of our tests". The main issue was that these were simple operations, since it was not really possible to define a test case, that we can use to apply to the general case. Our optimistic locking test was also dependent on how it recovers from a collision.

Henry
Ernest Friedman-Hill
author and iconoclast
Marshal

Joined: Jul 08, 2003
Posts: 24183
    
  34

Thanks!
Swapnil Shroff
Ranch Hand

Joined: Mar 07, 2006
Posts: 58
But what if I make it like



Is it still thread safe?
Henry Wong
author
Sheriff

Joined: Sep 28, 2004
Posts: 18509
    
  40

Originally posted by Swapnil Shroff:
Is it still thread safe?


If the getName() or setName() methods were not atomic, then the answer is definitely "no".

In theory, the answer is also "no". It is possible for a compiler to inline the method, in combination of caching the variable, etc.


I am tempted to say "yes", because it should work, but quite frankly, I can also envision a new JVM, with new optimization techniques... so IMHO, I would say "no".

Henry
Swapnil Shroff
Ranch Hand

Joined: Mar 07, 2006
Posts: 58
Thanks Henry
Mr. C Lamont Gilbert
Ranch Hand

Joined: Oct 05, 2001
Posts: 1170



Still effectively atomic no?
[ February 26, 2007: Message edited by: Mr. C Lamont Gilbert ]
Swapnil Shroff
Ranch Hand

Joined: Mar 07, 2006
Posts: 58
I think it is not atomic as it can be divided in to more simpler code like


Am I right Henry?
Henry Wong
author
Sheriff

Joined: Sep 28, 2004
Posts: 18509
    
  40

Originally posted by Swapnil Shroff:
I think it is not atomic as it can be divided in to more simpler code like

Am I right Henry?


Yes, that is the easiest way to look at it.

Officially, however, it depends on the code itself. For example, a post increment of an int, is not atomic, because the compiler generates a separate get and set operation. As such, it is possible for the int to actually change between the get and set operation.

In this case, it is possible for the string to change, between the time the string is loaded, appended, and then stored back into memory. This means that it is possible for two threads, to call the append method, and for one of the appended strings to be lost.

Henry
Mr. C Lamont Gilbert
Ranch Hand

Joined: Oct 05, 2001
Posts: 1170

Just to clarify, I said effectively atomic.

Originally posted by Henry Wong:

...In this case, it is possible for the string to change, between the time the string is loaded, appended, and then stored back into memory. This means that it is possible for two threads, to call the append method, and for one of the appended strings to be lost.

Henry



No moreso than with

Which you did call atomic right? The point I am making is they share the same level of atomicity.
[ February 26, 2007: Message edited by: Mr. C Lamont Gilbert ]
Henry Wong
author
Sheriff

Joined: Sep 28, 2004
Posts: 18509
    
  40

Originally posted by Mr. C Lamont Gilbert:
Just to clarify, I said effectively atomic.

No moreso than with

Which you did call atomic right? The point I am making is they share the same level of atomicity.


Actually (assuming the volatile example for safety)... I don't agree.

For example, let's say that the original name was "orig". And two threads try to set it, one to "one" and the other to "two". The result will either be "one" or "two". There is actually no way, it can be a third choice.

In the append method example, let's say that the original name was "orig". And two threads try to append to it, one with "one" and the other with "two". The results should either be "origonetwo" or "origtwoone". However, this is not true -- it is actually possible to get "origone" or "origtwo". This is because the append method is not "effectively" atomic.

For a better look at "effectively" atomic, let's take a look at the optimistic locking version.



At first glance, this method is not atomic, as it is possible to change the value, from the get() to the set(). However, in this version, the set is actually an atomic compare and set, which means that the operation will fail, if another thread changes the value between the get and the set.

In the example, if another thread changes the value between the get and set, it will simply retry the operation. So... while it is possible to get between the get and the set, the method will keep retrying until it is not interfered with. It is "effectively" atomic.

Henry
vu lee
Ranch Hand

Joined: Apr 19, 2005
Posts: 189
Since both method calls are atomic operations, I would say that the "least costly" method is to just change the variable to volatile

Since volatile prevents each thread to have its own local copy of the variable, suppose thread A, while in the middle of updating the variable, is being swapped out by the thread scheduler, what would be the current value of the variable. Would other threads be permitted to read the variable while it is currently modified by thread A.
Andrei Hager
Greenhorn

Joined: Mar 06, 2007
Posts: 10
I think "least costly" needs to be fleshed out a bit. If you're not expecting much contention on the protected data, and are playing it safe more than anything else, "cost" is the programming complexity you end up with, not a measure of performance.

Most synchronization techniques only show performance issues under high contention, and I doubt that a Student's name will change so much that it will matter in this case.

My "least costly" for this example would be to synchronize each method, and check that any private functions you have use the synchronized methods to get/set the name.

However, a Student with only a name is not worth much... if you add many other values and behaviors, you may want to look into a more complex synchronization scheme.
M Easter
Ranch Hand

Joined: Feb 11, 2007
Posts: 133
My take: the danger is that "least costly" can imply "most clever".

From my reading/experience, one had better understand the JVM, the Java memory model, and more before attempting to be clever with respect to threads.

Correctness first, then measure, then optimize.


M Easter
Software Composer - http://codetojoy.blogspot.com
 
 
subject: How to make a class thread safe
 
Similar Threads
Mock Question
Thread Safe Code
Class is Thread-Safe or not?
Is this class thread safe