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 Understanding threads better? Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


JavaRanch » Java Forums » Java » Threads and Synchronization
Bookmark "Understanding threads better?" Watch "Understanding threads better?" New topic
Author

Understanding threads better?

Amandeep Singh
Ranch Hand

Joined: Jul 17, 2008
Posts: 844
When i bounce my application, there is a class named EntryManager, gets loaded only one time. This class gets loaded by 1 thread only.

Now from the ui of application, whenever i call methods in that class. All work perfectly. All requests from different users go in to that 1 time loaded
class only. So i believe calls to the methods are made from 1000 users. the call is made to the method- calculateDuties

Example-



As per my requirements, now i need to use the instance variable which is defined at the class level. it is boolean NonWatch.

Question- Is this right approach to make class level variable which is not static, Which will shared by 1000 users. But inside the method,
I am initializing and reinitializing the variable for every method call. Is it possible, the boolean variable value can be interchanged between
different method calls.
I need to watch for precaution here.



SCJP 1.4, SCWCD 5, SCBCD 5, OCPJWSD 5,SCEA-1, Started Assignment Part 2
My blog- http://rkydesigns.blogspot.com
Amandeep Singh
Ranch Hand

Joined: Jul 17, 2008
Posts: 844
More Updates- I have seen the active count of threads inside this method it is 48. So any thread can access it.
Steve Luke
Bartender

Joined: Jan 28, 2003
Posts: 4181
    
  21

What is the goal of the NonWatch variable? Where is it going to be used? Why does it need to be an instance variable? What should happen if:


Given this information what should the value of NonWatch be at line 07. when Thread 1 wants to know the value of NonWatch. Is it false because the last time Thread 1 ran the code it was false? Or is it true because the last time the code was run (by anyone) the result was true?


Steve
Amandeep Singh
Ranch Hand

Joined: Jul 17, 2008
Posts: 844
NonWatch variable is being used here.



Ok i do see in your explanation, you have exposed the bug hidden.
Let's correct the code, Can we say it as now safe code ?


Steve Luke
Bartender

Joined: Jan 28, 2003
Posts: 4181
    
  21

No, it is still not safe. The problem with threads is that you have no control of the order in which they occur, unless you force it to.

Let's make an even simpler example of your code:


In this case, I would expect the method to ALWAYS return true, right? Because the last thing that the method does before returning is to set NonWatch to true. But if this is run in multiple threads, then we can have a problem if Thread1 executes lines 05. and 06., then Thread2 executes line 05., then Thread1 executes line 07. The order of events would be:

Do you see how Thread2 pre-empted the expected results of Thread1. We expect Thread1 to return true, but it may or may not actually do so, and what it returns is actually impossible to predict because you don't know what Thread2, Thread3, or Thread4 are doing, all or any of which may change the value of NonWatch at the wrong time.

So to put it more generally, whenever you have more than 1 step in a method which relies on the correct value of a variable (which is to say the variable's use is not atomic), then the code is NOT Thread Safe unless it is local to the method or the multiple steps are synchronized to make them function as a single whole. So to fix my above simple example I could do:


Your code has the same problem. You 'initialize' the value to true or false then later you make a comparison that relies on the value being set correctly. You can't do this, because someplace between setting it to true and making the comparison another thread may set it to false, making the whole method break (probably in both Threads).

So you could fix it a number of ways, but to know which is appropriate I would need to know why you need NonWatch at all and who is supposed to see what values. Is the latest value important? Is it the 'current thread's' value? If this is part of the web app we are talking about, would it be each user which needs to have a consistent value?
Amandeep Singh
Ranch Hand

Joined: Jul 17, 2008
Posts: 844
So you could fix it a number of ways, but to know which is appropriate I would need to know why you need NonWatch at all and who is supposed to see what values.

NonWatch helps me to decide whether the particular piece of code needs to be executed or not. Basically it will be used in a if logic condition.
For each user, this method is called. So i believe it should not intermix with other users. So for each user, the calculation will be restricted to their passed parameters.


Latest value is important in the context of each user. That is the whole point i am worried of.

Is it the 'current thread's' value? If this is part of the web app we are talking about, would it be each user which needs to have a consistent value?

It is not a web application. the front end is html/javascript and the backend is pure java. Yes, each user needs to have its own consistent value.
Steve Luke
Bartender

Joined: Jan 28, 2003
Posts: 4181
    
  21

Amandeep Singh wrote:
Is it the 'current thread's' value? If this is part of the web app we are talking about, would it be each user which needs to have a consistent value?

It is not a web application. the front end is html/javascript and the backend is pure java. Yes, each user needs to have its own consistent value.


It doesn't matter really if the front end is HTML/javascript or not - really if you are using JSP/Strunts/JSF, etc... that amounts to HTML and javascript to the end user anyway. So if users access this program from a web page (or series of web pages) and the application itself runs on a server (JEE server) then I would consider this a web application.

Anyway, back to the question:

You have a multi-threaded application. The value must be stored for each USER, and a USER may span multiple different threads (different requests).
1) The object where NonWatch is stored should probably be stored in a scope only one USER gets to see - typically the session.
2) You still need to synchronize properly to make sure the same user accessing the method from multiple requests at the same time gets consistent results.



But this assumes you can have an EntryManager for each User. If that is not the case, and you can only have one EntryManager for the entire application then you are better off NOT using a variable to store the boolean value in. Instead, re-calculate it each time. It will be safer and cleaner.
Amandeep Singh
Ranch Hand

Joined: Jul 17, 2008
Posts: 844
This code will not help me in my situation. I think in last example, you got my intention wrong.

If that is not the case, and you can only have one EntryManager for the entire application then you are better off NOT using a variable to store the boolean value in. Instead, re-calculate it each time. It will be safer and cleaner.

Yes in my situation, i am using a 1 EntryManager for the the entire application.

So i understand from you, that class variables are not safe to keep the result stored in a multi-threaded access.

The reason i am using class variable because in this way, i do not have to pass parameters in and around the methods. Just using class variable will solve my problem. Since it is a multithreaded access, things can go wrong.

my Solution-
it would be to pass local parameters only in and around the method.

out of curiosity Question- In case of beans, we do make class variables. But we do new Bean(), that's why it is safe there in case of multi-threaded applications.
Steve Luke
Bartender

Joined: Jan 28, 2003
Posts: 4181
    
  21

Amandeep Singh wrote:This code will not help me in my situation. I think in last example, you got my intention wrong.

If that is not the case, and you can only have one EntryManager for the entire application then you are better off NOT using a variable to store the boolean value in. Instead, re-calculate it each time. It will be safer and cleaner.

Yes in my situation, i am using a 1 EntryManager for the the entire application.

So i understand from you, that class variables are not safe to keep the result stored in a multi-threaded access.


Correct.


The reason i am using class variable because in this way, i do not have to pass parameters in and around the methods. Just using class variable will solve my problem. Since it is a multithreaded access, things can go wrong.

my Solution-
it would be to pass local parameters only in and around the method.


Good solution. And if you are having trouble with a lot of parameters being passed around, you can make a method-local object designed specifically to hold those values so you only have to pass one object around that holds the values which are needed by the different methods.


out of curiosity Question- In case of beans, we do make class variables. But we do new Bean(), that's why it is safe there in case of multi-threaded applications.

Yes. It is all about Scope. A Bean which holds instance variables would be created only in the scope were all that data should be available - once per request or once per user for example.
Amandeep Singh
Ranch Hand

Joined: Jul 17, 2008
Posts: 844
you are so good in knowledge, that i would suggest to become Bartender soon.
 
GeeCON Prague 2014
 
subject: Understanding threads better?