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 Static Methods with local variables.. Thread Safe? Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Java » Threads and Synchronization
Bookmark "Static Methods with local variables.. Thread Safe?" Watch "Static Methods with local variables.. Thread Safe?" New topic
Author

Static Methods with local variables.. Thread Safe?

John Bateman
Ranch Hand

Joined: Mar 09, 2000
Posts: 320
Hi
First off let me say that my answer to my own question would be. There's is a synchronization problem, you have to synchronize around the collection someList.
Now the problem.. hehe..
I have static methods in a class, these methods have no synchronization but there's a collection defined in the method. This collection used to add a list of 'items' to be returned to the user.
Will this cause multiple threads running in this method to overwrite the information that the other thread is adding, and effectively cause all the thread currently using this static method to 'share' the same collection?
I have supplied code as an example.

Thread 1 enters and sstarts populating he list with even number Integers. In other words the someObject is an Integer. In this case respectively the numbers 2, 4 and 6.
All of a sudden Thread 2 enters, doesn't the 'new' command kill the old ArrayList (reconstructs is) and erases the info in someList? In addition thread two then adds a list of odd Integers 3,5,7 and 9.
Thread 1 continues to run adding more even Integers (8,10,12)
We'll addume that Thread 1 and Thread 2 pretty much finish at this point
Would the ArrayList (someList) now contain..(3,5,7,9,8,10,12)? Would it contain (2,4,6,3,5,7,9,8,10,12) or will each thread get it's proper information sent back to it.
Any information would be helpful.
Thanks alot.
[ May 11, 2002: Message edited by: Dirk Schreckmann ]

SOURCE CODE should be SURROUNDED by "code" tags.
Dirk Schreckmann
Sheriff

Joined: Dec 10, 2001
Posts: 7023
Moving this to the Threads and Synchronization forum...


[How To Ask Good Questions] [JavaRanch FAQ Wiki] [JavaRanch Radio]
John Bateman
Ranch Hand

Joined: Mar 09, 2000
Posts: 320
Originally posted by Dirk Schreckmann:
Moving this to the Threads and Synchronization forum...

I am curious why this was moved. It's NOT really a Thread question, I am more concerned about the semantics of the STATIC keyword.
Jim Yingst
Wanderer
Sheriff

Joined: Jan 30, 2000
Posts: 18671
Actually it turns out not to depend on the static keyword at all. When a variable is defined locally in a method, and multiple threads run that method at the same time, each thread sees a different copy of the variable. There is no communication, intentional or otherwise, between threads by means of their effects on local variables. This is true whether the method is static or non-static.
I'm a bit perplexed by your comment

If this is intended to mean something like "pretend this comment here is replaced by some other code which might change 'flag'", then you're fine - I understand. But if you mean "assume that there's some code elsewhere that might eventually change 'flag'", then you're mistaken. In the code as written, the variable 'flag' will always be true, and someList will just keep adding references to anObject until an OutOfMemoryError is thrown. No other thread can affect flag, becuase flag is a local variable.
Hope that helps...


"I'm not back." - Bill Harding, Twister
John Bateman
Ranch Hand

Joined: Mar 09, 2000
Posts: 320
Hi
Thanks for your comments Jim.
Yes you are right, I meant 'replace this comment with code that 'will' eventually change flag so it's not an endless loop.
So if you are saying that each 'thread' that runs in the static method has it's own copy of the variable/object in question. What's the point of a Static method?
I always understood that a static method means it's a class method and that all threads using this method use the 'same' copy. Am I confusing this with a static variable?
Jim Yingst
Wanderer
Sheriff

Joined: Jan 30, 2000
Posts: 18671
So if you are saying that each 'thread' that runs in the static method has it's own copy of the variable/object in question.
Yes. This is true for any local variable, whether the method is static or not. But if a class variable or instance variable is accessed, those variables are shared by all threads acting on the same class or instance.
What's the point of a Static method?
It allows you to call a method without first having an instance of the class. If a method doesn't need to use any of the instance variables or the "this" reference, you might as well make it static, for greater flexibility of use. But it doesn't really have much to do with being thread-safe.
I always understood that a static method means it's a class method and that all threads using this method use the 'same' copy. Am I confusing this with a static variable?
I think you're confusing it with a static variable. In one sense we could say a method is always shared by all instances or threads that invoke it - the bytecodes that represent what a method will do are generally only stored in one place, and accessed from there by all instances and threads as necessary. But that's not really very important. What is important is that the data being accessed by the methods are important, and behave differently depending on whether they are held in class variables, instance variables, or local variables.
Pho Tek
Ranch Hand

Joined: Nov 05, 2000
Posts: 761

Jim,
Are you saying then that if I have a class
skeleton of this sort:

Then i is actually not thread safe. One way
to make this thread safe would be to changed
the i member variable into an instance variable.
Right ?
Thanks
Pho


Regards,

Pho
abhay bansal
Greenhorn

Joined: Nov 26, 2009
Posts: 8
i have a class with a static method let say it be

class A
{
public static void doSomething()
{
// do something
}
}

Wont this be called one by one by the multiple threads? This method being static, wont it have only a single copy accessed by all the threads.

Wont the threads wait if a large load is put onto the function?
Steve Luke
Bartender

Joined: Jan 28, 2003
Posts: 4181
    
  21

abhay bansal wrote:
Wont this be called one by one by the multiple threads? This method being static, wont it have only a single copy accessed by all the threads.

Wont the threads wait if a large load is put onto the function?


Hi Abhay,

No, as was mentioned earlier in this thread, the actual method byte code only exists in memory once - but this is the same for static or instance methods and it has nothing to do with how many Threads can call the method at one time. Each Thread has its own call stack, and can execute the code in the static method concurrent to other threads. Simply having a static method does NOT mean that only one Thread can access the method at one time. To get that functionality you need a synchronized method.

The keyword static on a method or variable does not imply or grant any implicit synchronization on the code in the method. The methods still need to be explicitly synchronized (either using the synchronized keyword on the method declaration or by providing a synchronized block).

Steve
Paul Clapham
Bartender

Joined: Oct 14, 2005
Posts: 18541
    
    8

Or to put it another way: static/instance and synchronized/nonsynchronized are orthogonal concepts. There's nothing in one of those two pairs of terms which has any effect on the other pair.
Steve Luke
Bartender

Joined: Jan 28, 2003
Posts: 4181
    
  21

Pho Tek wrote:Jim,
Are you saying then that if I have a class
skeleton of this sort:

Then i is actually not thread safe. One way
to make this thread safe would be to changed
the i member variable into an instance variable.
Right ?
Thanks
Pho


I know this is a 7 year old question (Pho, I hope you haven't been waiting for an answer ;-) but since this thread was brought up to the top I thought I would address this question for future readers.

Then i is actually not thread safe.
I don't think you should consider a VARIABLE thread-safe or not. The code which uses the variable can be thread-safe or not. It should be about how safe the code is that works on the variable. That said, the code as outlined is probably not thread-safe.

One way to make this thread safe would be to changed
the i member variable into an instance variable.


Making code thread-safe is a bit more invovled than adding or removing keywords (in practice anyway). Will making the variable i an instance variable make your class thread-safe? That depends. How is i used? If it needs to be static (shared by all instances or accessed from a static context) then making it an instance variable will break the class, so it won't matter if it is thread-safe or not. If it really belongs to an Object (instance) or type Foo, then you can't access it from the static method doSomething() anyway. So swapping between instance vs static members is not something you should do in order to play with thread safety (even if it had an affect) - that decision (static or not) needs to be made by the design of the class and how it is used.

Secondly, just as I said to Abhay about static not implyin thread-safety, neither does the variable being non-static. If i is non-static and it is accessed from multiple threads then you still have to worry about thread safety - making an instance value does not make them go away because the same instance may be used in multiple different threads. Then you have to consider how instances of the class are used and how the variable i is used inside the method(s) that use it. You may need to provide some explicit synchronization (for example if the instance is used in multiple threads and the variable is both read and modified), or you may not (if an instance is guaranteed not to escape one particular thread, or if the value is only read, or ...).
abhay bansal
Greenhorn

Joined: Nov 26, 2009
Posts: 8
Actually my question was not related to thread safety. It was on performance. I have multiple threads accessing the static method. All these methods will create a copy of this static method onto their stack and if at run time a bombard a static method with a large number of threads my JVM will show a out of heap exception.
Is this thing true? I am just confirming.
Paul Clapham
Bartender

Joined: Oct 14, 2005
Posts: 18541
    
    8

Of course it doesn't make the least bit of difference whether that method is static or not.

And there isn't anything making copies of any methods, but it's true that there is one copy of any local data belonging to the method for each active thread.

And it's also true that you can't create an infinite number of threads, and that at some point on the way to infinity you will get an OutOfMemoryError.
abhay bansal
Greenhorn

Joined: Nov 26, 2009
Posts: 8
There is some bytecode that exists for a particular thing. A method with have the same. There will be some overhead. Obviously every thread will have a stack in which it keeps variables as per the scope.

I am talking about a method somewhere there being accessed by multiple threads. I know all about the straight implementations, and I gave it a thought. I have seen a performance degradation using static methods(Class level) as compared to the non-static methods(Object level) for the same number of threads.
Paul Clapham
Bartender

Joined: Oct 14, 2005
Posts: 18541
    
    8

abhay bansal wrote:I have seen a performance degradation using static methods(Class level) as compared to the non-static methods(Object level) for the same number of threads.

You could certainly arrange this by having the static method synchronize on their class (i.e. the same monitor for all threads) and by having the instance methods synchronize on their object (i.e. different monitors for all threads). That would be the common case where you just declare the methods to be synchronized without saying on what. Then blocking would occur in the "static" case but not in the "instance" case.

When you do comparisons you should make sure you know the differences between the things you are comparing. That single sentence doesn't tell us enough about your comparison to know if it's meaningful or not.
abhay bansal
Greenhorn

Joined: Nov 26, 2009
Posts: 8
I am not talking about the thread safety.

Consider a class

Class A{

public static doOpA()
{
// do something
}

}

Class B{

public doOpB()
{
// do Something
}

}

Where the doOpA and doOpB function having the same content. Now i have multiple threads accessing the method doOpA say x threads and there are another set of x threads accessing the method doOpB. The performance was seen better in the latter case. Hope this makes it clear.
Steve Luke
Bartender

Joined: Jan 28, 2003
Posts: 4181
    
  21

It is always best to test these things using real, common code so we can see what you mean. Here is an example I wrote to do the test:


Note, the code was designed to make it so the work consumes CPU and the loop can't be optimized away (the JVM seemed much better at optimizing the static content then the non-static content).

You run the code like:
java forums.tests.speed.StaticSpeedDecrease
to get non-static runs and
java forums.tests.speed.StaticSpeedDecrease static
to get static runs.

On my machine, my (4) CPUs spiked during the majority of the run and the results were very consistent. Over about 30 or so runs each, static code ran 30 ms slower than non-static code (on average). If you took any 4 trials and grouped them together then averaged those runs you would see the same 30 ms difference between static and non-static runs.

My guess would have been there was no difference so I am thoroughly surprised to see that there is an measurable (if small) difference between them. Still, I think this comes under the micro-optimization category. , I would let the class design and usage dictate my choice between static / non-static rather than possible speed gains. I don't understand where that speed gain is coming from but it is minor and it is may be runtime specific.
Fidel Edwards
Ranch Hand

Joined: Mar 19, 2008
Posts: 231
Steve Luke wrote:Over about 30 or so runs each, static code ran 30 ms slower than non-static code (on average). If you took any 4 trials and grouped them together then averaged those runs you would see the same 30 ms difference between static and non-static runs.

My guess would have been there was no difference so I am thoroughly surprised to see that there is an measurable (if small) difference between them. Still, I think this comes under the micro-optimization category. , I would let the class design and usage dictate my choice between static / non-static rather than possible speed gains. I don't understand where that speed gain is coming from but it is minor and it is may be runtime specific.


Nice Example ! But something which is blowing my mind. First I run the program the result is
It took 6483ms to run 100 Threads with non-static method calls.
It took 6905ms to run 100 Threads with static method calls.


Then for understanding I commented join().Now the results are
It took 9669ms to run 100 Threads with non-static method calls.
It took 9357ms to run 100 Threads with static method calls.


I executed this program around 10 times.But found the almost same proportional figures. Here I am stumbled with the use of join() and without join(). Can anybody give me the clear picture of what is exactly going behind the scene.


Thanks in advance !




God Gave Me Nothing I Wanted, He Gave Me Everything I Needed.
OCPJP6
Steve Luke
Bartender

Joined: Jan 28, 2003
Posts: 4181
    
  21

The only change you made was to comment out the join and you saw that 1) the test took longer and 2) the non-static run took longer than the static one? The join() call makes the main thread wait for the worker thread to complete. So putting it in the loop makes the main thread wait for all the worker threads to complete before reporting how long it took to run. I would think the result would be that the test reported finished results much quicker since the work wasn't actually completed.
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: Static Methods with local variables.. Thread Safe?