aspose file tools*
The moose likes Java in General and the fly likes Java assignment issues Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Java » Java in General
Bookmark "Java assignment issues" Watch "Java assignment issues" New topic
Author

Java assignment issues

Bob Hunt
Greenhorn

Joined: Mar 26, 2010
Posts: 5
Hi,

I've got some questions about Java's assigment.

- Strings

I've got a class:



I'm using "synchronized" in my setter, and avoiding it in my getter, because in my app, there are a tons of data gettings, and very few settings. Settings must be synchronized to avoid inconsistency. My question is: is getting and setting a variable atomic? I mean, in a multithreaded environment, Thread1 is about to set variable s, while Thread2 is about to get "s". Is there any way the getter method could get something different than the s's old value or the s's new value (suppose we've got only two threads)? In my app it is not a problem to get the new value, and it is not a problem to get the old one. But could I get something else?

- What about HashMap's getting and putting?

considering this:


Is putting and getting atomic? How does HashMap handle putting an element into it? Does it first remove the old value and put the now one? Could I get other than the old value or the new value?

I've asked these questions here: link (sorry if I'm not allowed to link in this forum), but I'm confused.

I thought that Strings would be OK, and I'd have some trouble with HashMap. In the page above, a guy said "In the Java memory model, if there's no synchronization between the setter thread and the getter thread, it's possible that the getter thread will never get the updated value". I don't get it.
Let's say: "35 sec 300 millisec" I get the value, it is the old one. "35 sec 500 millisec" I set the value, than "50 sec xxx millisec" I try to get the new one? How come it is possible I won't get the new value ever?

My app is a "blog engine" like app. I store the first X (let's say 10) of the newly created entrys in a variable. It's is not a problem the users not get the up to date version of the entrys, because they could refresh the page if they wanted to. I make about 20 entrys in one day (setter), but I've got hundreds of thousands of visitors a day. It is not efficient (I think) to synchronize the getter methods (I've got quite a lot getter methods like the above, e.g. addons getting, ratings etc.). (No, I haven't got hundreds of thousands of visitors a day yet, but I want my app to be able to handle that)

Thanks in advance!
Henry Wong
author
Sheriff

Joined: Sep 28, 2004
Posts: 18847
    
  40

Before I answer your question, lets put a little perspective around it.

Bob Hunt wrote:
My app is a "blog engine" like app. I store the first X (let's say 10) of the newly created entrys in a variable. It's is not a problem the users not get the up to date version of the entrys, because they could refresh the page if they wanted to. I make about 20 entrys in one day (setter), but I've got hundreds of thousands of visitors a day. It is not efficient (I think) to synchronize the getter methods (I've got quite a lot getter methods like the above, e.g. addons getting, ratings etc.). (No, I haven't got hundreds of thousands of visitors a day yet, but I want my app to be able to handle that)



Perspective view #1:

Five years ago, we did a measurement of how long it takes to grab a synchronized lock in an uncontended manner -- and we got a result of around 80 nanoseconds. This was using a beta version of Java 5.

Now let's assume that the GA Java 5 didn't improved much better than that (unlikely), and Java 6 didn't improve much better than that (unlikely), and computers have not improved much in the last five years (very unlikely).

Also, to be conservative, let's assume that it is always contended. And that it takes lots of time to get and return the variable. So much so that instead of 80 nanoseconds, let's assume the getter takes 1000 nanoseconds -- or 1 micro seconds.

What does this mean? Well it means that you can call the synchronized getter at a rate of about 1 million times a second.

Henry




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

Joined: Sep 28, 2004
Posts: 18847
    
  40

Perspective view #2:

Let's assume the getter is synchronized. How many times will you call it during a transaction? Ideally once, at the beginning of the transaction. (as you already stated that you don't care about having a slightly older version). But let's assume that you don't care and call it around a 100 times during the transaction. This means that you can only do 10,000 transactions per second -- as limited by the getter.

Okay, what will your blog do? Will it access the database? Will it handle networked requests? Will it do parsing of the request? Will it generate the response for the users? And of course, what is the actually work that your blog is supposed to do? Now, compare that with the 100 microseconds (for the 100 getter calls) that will be used to call the synchronized getter.

Are they in the same ballpark? Or are we talking about adding a drop of water into bucket full of water?

Henry

Henry Wong
author
Sheriff

Joined: Sep 28, 2004
Posts: 18847
    
  40

Bob Hunt wrote:
I thought that Strings would be OK, and I'd have some trouble with HashMap. In the page above, a guy said "In the Java memory model, if there's no synchronization between the setter thread and the getter thread, it's possible that the getter thread will never get the updated value". I don't get it.
Let's say: "35 sec 300 millisec" I get the value, it is the old one. "35 sec 500 millisec" I set the value, than "50 sec xxx millisec" I try to get the new one? How come it is possible I won't get the new value ever?


Basically, the answer is referring to caching (specifically the hardware caches). Modern computers uses multiple processors. Or multiple cores within the same processor. In order for the processor to not wait for memory (because relatively, it is slow), there are multiple levels of caches -- caches shared between cores, caches shared between processors, etc. etc.

Part of the synchronization process, is to flush it all out to memory, and to reload it all from memory. And what is referred to here is the chance that the getter could be working off of an old version of the data because it never fetched the latest version from memory -- which didn't happen because of the lack of synchronization.


As for not "getting the new value" ever? That is unlikely. In fact, you probably never notice it in your testing. The reason is, the JVM does a lot of things -- and a lot of those things require that everything be saved to memory. I agree that there is a chance you will not see the new data for some time. But for a "some time" that is more than a few milliseconds, that is unlikely.

Henry



Bob Hunt
Greenhorn

Joined: Mar 26, 2010
Posts: 5
Thank you very much for your detailed answers. I will take your advices.

There are two things that I was / am afraid of related to synchronization.

1. When there are a lot of visitors that want to get the same piece of data (a String for example), and they have to get in to a synchronized getter method for this purpose, there is a chance one / some of them will never get in the synchronized method because all the others will come before it / them (by others, I mean every second the application gets a tons of request for this data)

2. When I synchronize the getters, a request must get in, then get out, then comes another request etc. But if I don't use synchronization, they can get the requested data simultaniously improving the performance.

What do you think about these?
Jim Hoglund
Ranch Hand

Joined: Jan 09, 2008
Posts: 525
Bob Hunt wrote: ... My question is: is getting and setting a variable atomic? I mean, in a multithreaded environment, Thread1 is about
to set variable s, while Thread2 is about to get "s". Is there any way the getter method could get something different
than the s's old value or the s's new value (suppose we've got only two threads)? ...

Things become atomic when you work at the primitive level. For example, if 'int a' is assigned (1024 + 256),
you will never see a == 256. But since any useful setValue() call will be a sequence of statements that the
JVM can interrupt, consistency can be harmed. Even a getValue() that changes state, a counter for example,
can also be vulnerable. I don't know if building a string, as in your example is atomic, but I would not take
the chance. Using 'synchronized' can provide very inexpensive quality assurance.

On your point 2), the only additional time is that needed to secure the lock. It is not possible for many threads
to access shared data more quickly since only one runs at a time. Without the object lock, the active thread
can change to a competing thread during the method, leading to the data consistency risk. With the lock the
synchronized block of code will complete before another thread can access the same code block. This does
not mean the JVM will not change the active thread mid-method, it just won't activate a thread that is waiting
for the same lock.

Jim ... ...


BEE MBA PMP SCJP-6
 
wood burning stoves
 
subject: Java assignment issues