File APIs for Java Developers
Manipulate DOC, XLS, PPT, PDF and many others from your application.
http://aspose.com/file-tools
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

Threads behaving weirdly

 
Anish Shah
Greenhorn
Posts: 20
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi everyone,
I am stuck into this probelem very badly..i have never seen such a problem before..Thread bottleneck somewhere is the issue i guess,,, please have a look at the code patiently.. and do reply.. you guys are my last hope on this thing..Thank YOU...

The Bank method is called by another method which runs 50 threads , so at a time 50 threads could enter this method to record Debit...




-------------------------------------------------------------------------------------------------------------------------------




Answer:
Record time is 9014 millis for 5000 increments or 5000 calls to recordDebit()

One can see in the answer that its a huge number when one is expecting it to be somewhere around:
EXPECTED ANSWER:
5000 * 800 nanos( it takes 800 nanos for very increment) = 4000000 = 4 millis and its like 9014 millis

How is there such a huge difference ??? I have bruised thorugh it for like 3 days... i have lost all my hope.. Please help..Also look at the next code..

When i go to see in the log .. it shows me that every record took like from 2000 nanos to 6 to 7 millis i.e.7000000...
How is this even possibly possible ??? where did it get all this extra time from...it should not be more than some 700 to 900 nanos ..
Is there a bottleneck somewhere ???


Now part 2:
This thing has fazzed, dazzled , destroyed me.. I could not understand this and it has tossed all my concepts into the cupboard..

Same stuff: JUST HAVE A LOOK AND ENJOY AND TELL ME WHATS GOING ON...Same code.. different way of incrementing data i.e synchronization is at a different place..but results are very highly improved...





The Bank method is called by another method which runs 50 threads , so at a time 50 threads could enter this method to record Debit...
----------------------------------------------------------------------------------------------------------------------------------


ANSWER: Record is 135 millis for 5000 increments or 5000 calls to recordDebit()


Expected time was : 5000 * 2500 = 125000000 = 125 millis (WOW .. AS EXPECTED)

Please don't ask me why this code has been written this way..i know it goes and increment and does the same thing...but somehow when i measured it..
overall time or the accumulated time for both codes varied like in huge numbers...even though latter code is actually a superset of previous code..

HOW IS THERE SUCH A HUGE DIFFERENCE BETWEEN THE NUMBERS ???
COULD BE BECAUSE OF THE POINT OF SYNCHRONIZATION ???

Thank you..for going through all this..
[ September 27, 2008: Message edited by: Bear Bibeault ]
 
Henry Wong
author
Marshal
Pie
Posts: 20823
75
C++ Chrome Eclipse IDE Firefox Browser Java jQuery Linux VI Editor Windows
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
HOW IS THERE SUCH A HUGE DIFFERENCE BETWEEN THE NUMBERS ???
COULD BE BECAUSE OF THE POINT OF SYNCHRONIZATION ???


Well, how would you test any speculations?

Is it due to the synchronizations? Maybe. What happens when you remove the synchronizations? (assuming it still works)

Is it due to the fact that you have 50 threads share one processor? Maybe. What happens when you drop the number of threads down to one?

Henry
 
Steve Luke
Bartender
Pie
Posts: 4181
21
IntelliJ IDE Java Python
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
If I understand what is being called in each thread correctly then:

In the first example you can't increment while you are logging data since both the incrementing and the logging methods are synchronized. When you synchronize a method the lock is the object which the method belongs to (the 'this' object).

In the second example, since you are synchronizing the increment on a different object then the one doing the logging you can log and increment at the same time. Most of your wasted time, then is probably spent waiting for the logging to finish (which most likely needs to access a log file, and IO is much slower than anything else you are doing).
 
Anish Shah
Greenhorn
Posts: 20
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
In the first example you can't increment while you are logging data since both the incrementing and the logging methods are synchronized. When you synchronize a method the lock is the object which the method belongs to (the 'this' object).


to reply on this,

both logging and incrementing can happen together as both use differnt shared data.. Logging does not require and data from 1st method so it can exclusively...
 
Steve Luke
Bartender
Pie
Posts: 4181
21
IntelliJ IDE Java Python
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by Anish Shah:

both logging and incrementing can happen together as both use differnt shared data.. Logging does not require and data from 1st method so it can exclusively...


Correction, both the logging and incrementing should be able to happen together, as both use different shared data. But since you use method locking you are preventing them from doing so. When you synchronize methods you are ensuring that only ONE synchronized method of a class can run at a time. So the fix is to synchronize inside the method with different locks. Having different debit and record locks will ensure that only one thread can access these fields at a time, but will make sure that a debit action doesn't block a record action, and vice-versa. Example:

[ September 25, 2008: Message edited by: Steve Luke ]
 
Anish Shah
Greenhorn
Posts: 20
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks for the replies..

Shit.. i m so naive at this.. Please correct me on this if i am wrong..

You mean to say if there are 5 synchornized methods in a class in a multithreaded system.. then ony one of those method can execute at a time..
i wish this is wrong.. please give me a good idea on it..
 
Ernest Friedman-Hill
author and iconoclast
Marshal
Pie
Posts: 24204
34
Chrome Eclipse IDE Mac OS X
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by Anish Shah:

You mean to say if there are 5 synchornized methods in a class in a multithreaded system.. then ony one of those method can execute at a time..
i wish this is wrong.. please give me a good idea on it..


Only one of those methods may be executing at a time on a given object. If a class has five synchronized instance methods, and your create five instances of the class, then five threads could call any of the five methods on any of the five objects, all at once. But if there's only one object, and all five threads want to call a different synchronized method on that one object, then yes, they need to wait.
 
Anish Shah
Greenhorn
Posts: 20
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Wow.. this is some awesomely new to me... so an object at a time can have only 1 synchronized method running unless and until it has multiple instances running...

Thanks a lot guys.. let me test it..
Thanks for all the replies.. will be back with the results soon..
 
Mark Waes
Greenhorn
Posts: 21
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I've just been studying this, and my understanding is that if an instance of an obect is being accessed via a synchronised method, then any other syncronised method of that instance is also locked. Non-sycronised methods are not locked, however...
 
Anish Shah
Greenhorn
Posts: 20
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Just was thinking about this whole synchronized waiting thing on the same object... Guys please tell me one thing.. say for example .. we are using the instance variable debit in 1st synchronized method and this same variable is used in another unsynchronized method where it is being just read.. so the read can happen on tihs instance variable without wait ??

Also, what would be the way out of this thing if we have multiple synchronized methods not using the same shared data in the same class i.e same instant..if we use synchronization within methods.would this help ??
how do we do this ??

Sorry if any of my question sound stupid to anyone.. I am just trying to learn something that i got to know very recently..
Thanks for all the replies..

Thank you..
 
Steve Luke
Bartender
Pie
Posts: 4181
21
IntelliJ IDE Java Python
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by Anish Shah:
Just was thinking about this whole synchronized waiting thing on the same object... Guys please tell me one thing.. say for example .. we are using the instance variable debit in 1st synchronized method and this same variable is used in another unsynchronized method where it is being just read.. so the read can happen on tihs instance variable without wait ??


If debit is a simple value like a primitive, then you would not need to synchonize to read it, unless you want to make sure that it is set before you read it. Take for example this:


If I call getDebit and the debit increment has not happened yet, I will get a zero, or whatever the pre-incrementing value was. This is fine and you don't risk any un-safe behavior. This is only true if you are only reading debit. If you need to change debit at all then you will need to synchronize. And if the debit is not a primitive or Immutable type then you should also synchronize reading (if it is a List for example, that you need to iterate over, or a custom object that has setter methods).

If you need more accuracy on the returned debit, that is, if one thread increments debit and you must have the latest value then you would want to synchronize getDebit on the same debitLock, so that if one thread is in the middle of incrementing the reading thread has to block until the increment is done, giving a more 'up-to-date' value.



Originally posted by Anish Shah:
Also, what would be the way out of this thing if we have multiple synchronized methods not using the same shared data in the same class i.e same instant..if we use synchronization within methods.would this help ??
how do we do this ??


My previous post shows you how to do this. You create individual Objects that do nothing but act as locks for the data they are meant to protect. You would not synchronize the method, but would use synchronized(lock) { } blocks like I have in my previous post. For example, I created a public final Object recordLock object. Only one thread at a time would be able to enter a synchronized(recordLock) { } block at a time. But another thread could enter a synchronized(debitLock) { } block while the first thread was in the synchronized(recordLock) { } block.

See my previous post for a full example.

Originally posted by Anish Shah:
Sorry if any of my question sound stupid to anyone.. I am just trying to learn something that i got to know very recently..
Thanks for all the replies..

Thank you..


None of your questions have been stupid. Please feel free to ask anymore that you might have. We will be happy to answer any we can. I hope I have been helping you understand this subject. It can be quite difficult to nail down, but is important especially with the growing multi-core computer world were multi-threading applications are under high demand...
 
Rahul Shilpakar
Ranch Hand
Posts: 132
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Orginally posted by : Anish Shah

Expected time was : 5000 * 2500 = 125000000 = 125 millis



As you said in very first post, i just wanted to say that the 5000 * 2500 = 12500000. there will be 5 ZEROS in front of 125. You mentioned 6 ZEROS and which does not equal to 125 millis.

Notice this. Best luck if it does match your expected result.
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic