How does ThreadLocal usage reduce reusability - java

The well acclaimed book JCIP says this about ThreadLocal usage :
It is easy to abuse ThreadLocal by treating its thread confinement property as a license to use global variables or as a means of creating "hidden" method arguments.
Thread-local variables can detract from reusability and introduce hidden couplings among classes, and should therefore be used with care.
What does it mean by saying that Thread-local variables can reduce reusability and introduce hidden couplings among classes?

They reduce reusability in much the same way that global variables do: when you method's computations depend on state which is external to the method, but not passed as parameters (i.e. class fields for example), your method is less reusable, because it's tightly coupled to the state of the object/class in which it resides (or worse, on a different class entirely).
Edit: Ok, here's an example to make it more clear. I've used ThreadLocal just for the sake of the question, but it applies to global variables in general. Assume I want to calculate the sum of the first N integers in parallel on several threads. We know that the best way to do it is to calculate local sums for each thread and them sum them up at the end. For some reason we decide that the call method of each Task will use a ThreadLocal sum variable which is defined in a different class as a global (static) variable:
class Foo {
public static ThreadLocal<Long> localSum = new ThreadLocal<Long>() {
public Long initialValue() {
return new Long(0);
}
};
}
class Task implements Callable<Long> {
private int start = 0;
private int end = 0;
public Task(int start, int end) {
this.start = start;
this.end = end;
}
public Long call() {
for(int i = start; i < end; i++) {
Foo.localSum.set(Foo.localSum.get() + i);
}
return Foo.localSum.get();
}
}
The code works correctly and gives us the expected value of the global sum, but we notice that the class Task and its call method are now strictly coupled to the Foo class. If I want to reuse the Task class in another project, I must also move the Foo class otherwise the code will not compile.
Although this is a simple example complicated on purpose, you can see the perils of "hidden" global variables. It also affects readability, since someone else reading the code will have to also search for the class Foo and see what the definition of Foo.localSum is. You should keep your classes as self-contained as possible.

A ThreadLocal is declared per thread - normally a field is declared per object of that class - Starting from this - there can be a whole lot of things that can go wrong if the ThreadLocal is misused.
If a thread passes through multiple objects , ( either of the single class or multiple classes ) , the ThreadLocal used by this thread is the same instance across all these instances. This is the coupling BG is talking about. The moment there is a coupling - the reusability becomes difficult and error prone.

Related

Thread Safety using final

Here is an example method for explaining thread safety:
class Counter {
private int counter = 0;
public void increment() {
counter++;
}
public int getValue() {
return counter;
}
}
In order to provide thread safety, there are several methods and I would prefer using AtomicInteger approach. However;
1. I am also wondering if I can provide thread safe by using final for the necessary variable(s). If so, how can I perform this?
2. Is one of the reason using final commonly in Java for variables and method arguments to provide thread safety?
In properly synchronized code, the final isn't needed.
E.g. if you would use:
class MyCounter{
private AtomicInteger c = new AtomicInteger();
public int inc(){return c.incrementAndGet();}
public int get(){return c.get();}
}
And you would share the MyCounter-instance with another thread, you need to make sure that there is a happens-before edge between writing c and reading c. This can be done in various ways e.g. you pass the MyCounter-instance to the constructor of some thread (thread start rule). Or you pass it through a volatile field (volatile variable rule) or a synchronized block (monitor lock rule).
This is typically called 'safe publication' and for a correctly synchronized system, this is all you need. If you don't pass the reference safely, you have a data race and weird problems can happen like seeing a partially constructed object. Therefore there is a second mechanism called initialization safety; so no matter if the reference to an object isn't published safely, initialization safety using final will act as a backup solution. The primary use-case for this AFAIK is security.
So for correctly synchronized code, there is no need for final.
That doesn't mean that you should not add finals. It has all kinds of benefits like no accidental changes and it is pretty informative. So I prefer to make as many fields final as possible.
Final has no meaning for method arguments from a memory model perspective, since they are private to a thread. Only shared memory needs to be dealt with in a memory model. Making arguments of a method final is a flavor issue. Some people want it, others don't. I'm not crazy about long method signatures and tend not to add them unless I'm writing some difficult code. But I would be fine if local variables and formal arguments would be final by default (like Rust).
I m just gonna add this with Erwan Daniel's answer .
Your
If you want a counter shared between all your Threads here is another version of your code.
class SharedCounter {
private AtomicInteger sharedCounter ;
public Counter(){
this.sharedCounter = new AtomicInteger(0);
}
public void increment() {
sharedCounter.getAndIncrement();
}
public int value() {
return sharedCounter.get();
}
The final will prevent your atomicInteger12 from changing the object it's using And you can freely set it's value.
final SharedCounter atomicInteger12 = new Counter() ;
No, the final keyword doesn't have anything in common with thread safety.
The final keyword on variables makes them immutable, you can't change their value anymore.
However, it's not like the const keyword in c++ where the whole variable content cannot change. In Java only the reference is immutable.
final AtomicReference<String> toto = new AtomicReference<>("text");
toto.set("new text"); // totally fine
toto = new AtomicReference<>("text"); // does not compile, as toto is immutable reference.
But, there is another keyword that fulfill what you are looking for. It's volatile. https://www.baeldung.com/java-volatile
In short, the value change on all thread simultaneously and is available immediately.
That's what is used in all the Atomic* Java classes.
Ex. https://github.com/AdoptOpenJDK/openjdk-jdk11/blob/master/src/java.base/share/classes/java/util/concurrent/atomic/AtomicInteger.java

How much more expensive is the creation of an object without data in Java instead of the use of static methods?

Java lacks the ability to specify interfaces for static methods. A method in an interface must be non static. This makes it impossible to specify requirements for Classes. Instead one is limited to specify requirements for Objects. This makes it also impossible for example to specify the singleton functionality in an interface, because in Java the singleton pattern requires to be implemented as a static method. Here is a nice article, which explains it, but it is only in German.
When one is forced to implement something as a functionality of an object instead of the functionality of a class, an instance of this object has to be created, before the functionality can be used. But such object has some special characteristic: it has no state, because class functionality has no state either. Theoretically the instance creation of an object without data can be optimized to an NOP, because all methods can be linked to the class instead of any object. Java could implement some kind of implicit singleton functionality.
But how it this actually handled?
Think about some kind of functionality without any state.
interface Adder<T> { T add(T ... arguments); }
Basically it would be sufficient to implement this as a static method:
class IntegerAdder implements Adder<Integer> {
public static Integer add (Integer ... arguments) { }
}
But because Java does not allow static interface methods it has to be implemented in a non static way. The result is, that when ever an IntegerAdder is required one has to create an instance.
IntegerAdder integer_adder = new IntegerAdder();
Integer a = 1;
Integer b = 2;
Integer c = integer_adder.add (1, 2);
I fear this might be slower than the version without the instance creation:
Integer a = 1;
Integer b = 2;
Integer c = IntegerAdder.add (1, 2);
But how much slower is it in reality? Is it possible for the Java compiler to optimize the first version in that way that it performs as fast as the second one? And is this actually done?
You can create an instance of IntegerAdder once and reuse it, it is thread safe. Also pay attention that Integer ... arguments leads to 1) using objects instead of primitive ints 2) creating an array to pass parameters. Both things should be avoided if performance is concern

Java: Static and thread safety in a Java EE application

I was wondering what the implications are for using static methods in a Java EE application.
For example: There is a class that handles converting of dates, reordering of strings etc.
All methods in this class are static.
These methods are used by Servlets.
Does this mean that the static methods need to be thread safe (in that if many users are using the application at the same time and are accessing the static method at the same time that there could be some issues)?
Edit I would like to know about this in the context of a web application - are two users going to hit the static methods at the same time and mess with each others result (of the static method)?
accessing the methods in parallel is fine, as long as there are not shared class variables; e.g. if the method declares its own stuff, you're good:
public static void thing() {
String x = "";
// do stuff with x
}
The above is fine.
String x = "";
public static void thing() {
// do stuff with x
}
This one isn't.
Does this mean that the static methods need to be thread safe (in that
if many users are using the application at the same time and are
accessing the static method at the same time that there could be some
issues)?
Only if there's shared state. If you're allocating new objects on the heap for each invocation then it's not an issue.
But I never like doing this sort of thing since introducing shared state immediately means you have thread-safety issues. I prefer to create an instance of a converter/helper class (object creation normally being negligible performance-wise). That immediately means you're thread-safe (provided you're not sharing state) and each instance can (for example) be customisable upon construction, to give different behaviours where required.
Of course there will be issues if you don't protect your static methods and they change the a state.
Consider this sample
public class GlobalCount {
private int count = 0;
public static void increment() {
count++; // that is : count = count + 1 (which means some thread may use the old value of count when assigning)
}
}
If more than one thread calls increment, you may lose some increments (that is you may have count smaller than the number of times the increment method was called.
So you have to set your method as synchronized :
public static synchronized void increment() {
count++;
}
If you think you don't have a shared state, be careful : many standard classes (for example SimpleDateFormat, as you're speaking of date formatting) aren't thread safe and may fail if an instance is called from more than one thread at the same time.
So, as soon as you have a static instance accessed from more than one thread, be very careful.

What is the gain from declaring a method as static

I've recently been looking through my warnings in Eclipse and come across this one:
It will give a compiler warning if the method can be declared as static.
[edit] Exact quote within the Eclipse help, with stress on private and final:
When enabled, the compiler will issue an error or a warning for
methods which are private or final and which refer only to static
members.
Yes I know I can turn it off, but I want to know the reason for turning it on?
Why would it be a good thing to declare every method possible as static?
Will this give any performance benefits? (in a mobile domain)
Pointing out a method as static, I suppose is showing that you don't use any instance variables therefore could be moved to a utils style class?
At the end of the day should I just turn this off 'ignore' or should I fix the 100+ warnings it has given me?
Do you think this is just extra keywords that dirty the code, as the compiler will just inlines these methods anyway? (kind of like you don't declare every variable you can final but you could).
Whenever you write a method, you fulfill a contract in a given scope. The narrower the scope is, the smaller the chance is that you write a bug.
When a method is static, you can't access non-static members; hence, your scope is narrower. So, if you don't need and will never need (even in subclasses) non-static members to fulfill your contract, why give access to these fields to your method? Declaring the method static in this case will let the compiler check that you don't use members that you do not intend to use.
And moreover, it will help people reading your code understand the nature of the contract.
That's why it's considered good to declare a method static when it's actually implementing a static contract.
In some cases, your method only means something relative to an instance of your class, and it happens that its implementation doesn't actually use any non-static field or instance. In such cases, you would not mark the method static.
Examples of where you would not use the static keyword:
An extension hook which does nothing (but could do something with instance data in a subclass)
A very simple default behavior meant to be customisable in a subclass.
Event handler implementation: implementation will vary with the class of the event handler but will not use any property of the event handler instance.
There is no concept with optimization here.
A static method is static because you explicitly declare that method doesn't rely on any instance the enclosing class just because it doesn't need to. So that Eclipse warning, as stated in documentation:
When enabled, the compiler will issue an error or a warning for methods which are private or final and which refer only to static members.
If you don't need any instance variable and your method is private (can't be called from outside) or final (can't be overriden) then there is no reason to let it be a normal method instead that a static one. A static method is inherently safer even just because you are allowed to do less things with it (it doesn't need any instance, you don't have any implicit this object).
I've no info on the performance, I suppose it is marginally better at most, since the code does not need to do dynamic dispatch based on the type.
However, a much stronger argument against refactoring into static methods is that currently using static is considered bad practice. Static methods / variables do not integrate well into an object oriented language and also, hard to test properly. This is the reason why some newer languages forego the concept of static methods/variables altogether, or try to internalize it into the language in a way that plays better with OO (eg Objects in Scala).
Most of the time, you need static methods to implement functions that are only using parameters as an input and producing an output using that (eg utility/helper functions) In modern languages, there is a first class Function concept that allows that, so static is not needed. Java 8 will have lambda expressions integrated, so we are moving into this direction already.
1. Declaring method static gives slight performance benefit, but what is more useful, it allows using it without having an object instance at hand (think of for example about factory method or getting a singleton). It also serves the documentational purpose of telling the nature of the method. This documentational purpose should not be ignored, as it gives immediate hint about the nature of the method to the readers of the code and users of the API and also serves as a tool of thinking for the original programmer - being explicit about the intended meaning helps you also think straight and produce better quality code (I think based on my personal experience, but people are different). For example, it is logical and hence desirable to distinguish between methods operating on a type and methods acting on an instance of the type (as pointed out by Jon Skeet in his comment to a C# question).
Yet another use case for static methods is to mimic procedural programming interface. Think of java.lang.System.println() class and the methods and attributes therein. The class java.lang.System is used like a grouping name space rather than an instantiable object.
2. How can Eclipse (or any other programmed or other kind of - biocomposable or non-biocomposable - entity) know for sure which method could be declared as static? Even if a base class is not accessing instance variables or calling non-static methods, by the mechanism of inheritance the things can change. Only if the method cannot be overridden by inheriting subclass, can we claim with 100% certainty that the method really can be declared static. Overriding a method is impossible exactly in the two cases of being
private (no subclass can use it directly and does not even in principle know about it), or
final (even if accessible by the subclass, there is no way to change the method to refer to instance data or functions).
Hence the logic of the Eclipse option.
3. The original poster also asks: "Pointing out a method as static, I suppose is showing that you don't use any instance variables therefore could be moved to a utils style class?" This is a very good point. Sometimes this kind of design change is indicated by the warning.
It is very useful an option, which I would personally make sure to enable, were I to use Eclipse and were I to program in Java.
See Samuel's answer on how the scope of the method changes.
I guess, this is the main aspect of making a method static.
You also asked about performance:
There might be a tiny performance gain, because a call to a static method
does not need the implicit "this" reference as parameter.
However, this performance impact is really tiny. Therefore, it's all about the scope.
From the Android Performance guidelines:
Prefer Static Over Virtual If you don't need to access an object's
fields, make your method static. Invocations will be about 15%-20%
faster. It's also good practice, because you can tell from the method
signature that calling the method can't alter the object's state.
http://developer.android.com/training/articles/perf-tips.html#PreferStatic
Well, the Eclipse documentation says about the warning in question:
Method can be static
When enabled, the compiler will issue an error or a warning for
methods which are private or final and which refer only to static
members
I think it pretty much says it all. If the method is private and final and only refers to static members, the method in question might just as well be declared static and by this, make evident that we only intend to access static content from it.
I honestly don't think there is any other mysterious reason behind it.
I was missing some numbers for the speed differences. So I tried to benchmark them which turned out to be not so easy: Java loop gets slower after some runs / JIT's fault?
I finally used Caliper and the results are the same as running my tests by hand:
There is no measurable difference for static/dynamic calls. At least not for Linux/AMD64/Java7.
The Caliper Results are here: https://microbenchmarks.appspot.com/runs/1426eac9-36ca-48f0-980f-0106af064e8f#r:scenario.benchmarkSpec.methodName,scenario.vmSpec.options.CMSLargeCoalSurplusPercent,scenario.vmSpec.options.CMSLargeSplitSurplusPercent,scenario.vmSpec.options.CMSSmallCoalSurplusPercent,scenario.vmSpec.options.CMSSmallSplitSurplusPercent,scenario.vmSpec.options.FLSLargestBlockCoalesceProximity,scenario.vmSpec.options.G1ConcMarkStepDurationMillis
and my own results are:
Static: 352 ms
Dynamic: 353 ms
Static: 348 ms
Dynamic: 349 ms
Static: 349 ms
Dynamic: 348 ms
Static: 349 ms
Dynamic: 344 ms
The Caliper Test class was:
public class TestPerfomanceOfStaticMethodsCaliper extends Benchmark {
public static void main( String [] args ){
CaliperMain.main( TestPerfomanceOfStaticMethodsCaliper.class, args );
}
public int timeAddDynamic( long reps ){
int r=0;
for( int i = 0; i < reps; i++ ) {
r |= addDynamic( 1, i );
}
return r;
}
public int timeAddStatic( long reps ){
int r=0;
for( int i = 0; i < reps; i++ ) {
r |= addStatic( 1, i );
}
return r;
}
public int addDynamic( int a, int b ){
return a+b;
}
private static int addStatic( int a, int b ){
return a+b;
}
}
And my own Test class was:
public class TestPerformanceOfStaticVsDynamicCalls {
private static final int RUNS = 1_000_000_000;
public static void main( String [] args ) throws Exception{
new TestPerformanceOfStaticVsDynamicCalls().run();
}
private void run(){
int r=0;
long start, end;
for( int loop = 0; loop<10; loop++ ){
// Benchmark
start = System.currentTimeMillis();
for( int i = 0; i < RUNS; i++ ) {
r += addStatic( 1, i );
}
end = System.currentTimeMillis();
System.out.println( "Static: " + ( end - start ) + " ms" );
start = System.currentTimeMillis();
for( int i = 0; i < RUNS; i++ ) {
r += addDynamic( 1, i );
}
end = System.currentTimeMillis();
System.out.println( "Dynamic: " + ( end - start ) + " ms" );
// Do something with r to keep compiler happy
System.out.println( r );
}
}
private int addDynamic( int a, int b ){
return a+b;
}
private static int addStatic( int a, int b ){
return a+b;
}
}
The methods you can declare as static are the ones that don't require instantiation, such as
public class MyClass
{
public static string InvertText(string text)
{
return text.Invert();
}
}
Which you can then in return call out in any other class without instanciating that class.
public class MyClassTwo
{
public void DoSomething()
{
var text = "hello world";
Console.Write(MyClass.InvertText(text));
}
}
... But that's something you probably already know. It doesn't give you any real benefits per se, other than making it more clear that the method doesn't use any instance variables.
In other words, you can most safely just turn it off completely. If you know you will never use a method in other classes (in which case it should just be private), you don't need it to be static at all.

What's the difference between anonymous classes in Java and closures?

It looks like anonymous class provides the basic functionality of closure, is that true?
There is almost no difference. In fact the there is an old saying about closures and objects. Closures are the poor man's object, and objects are the poor man's closure. Both are equally powerful in terms of what they can do. We are only arguing over expressiveness.
In Java we are modeling closures with Anonymous Objects. In fact a little history here is that originally Java had the ability to modify the outward scope without the use of final. This works and worked fine for Objects allocated in the local method scope, but when it comes to primitives this caused lots of controversy. Primitives are allocated on the stack so in order for them to live past the execution of the outer method Java would have to allocate memory on the heap and move those members into the heap. At that time people were very new to garbage collection and they didn't trust it so the claim was Java shouldn't allocate memory without explicit instruction from the programmer. In efforts to strike a compromise Java decided to use the final keyword.
http://madbean.com/2003/mb2003-49/
Now the interesting thing is that Java could remove that restriction and make use of the final keyword optional now that everyone is more comfortable with the garbage collector and it could be completely compatible from a language perspective. Although the work around for this issue is simple to define instance variables on your Anonymous Object and you can modify those as much as you wish. In fact that could be an easy way to implement closure style references to local scope by adding public instance variables to the anonymous class through the compiler, and rewriting the source code to use those instead of stack variables.
public Object someFunction() {
int someValue = 0;
SomeAnonymousClass implementation = new SomeAnonymousClass() {
public boolean callback() {
someValue++;
}
}
implementation.callback();
return someValue;
}
Would be rewritten to:
public Object someFunction() {
SomeAnonymousClass implementation = new SomeAnonymousClass() {
public int someValue = 0;
public boolean callback() {
someValue++;
}
}
implementation.callback();
// all references to someValue could be rewritten to
// use this instance variable instead.
return implementation.someValue;
}
I think the reason people complain about Anonymous inner classes has more to do with static typing vs dynamic typing. In Java we have to define an agreed upon interface for the implementor of the anonymous class and the code accepting the anonymous class. We have to do that so we can type check everything at compile time. If we had 1st class functions then Java would need to define a syntax for declaring a method's parameters and return types as a data type to remain a statically typed language for type safety. This would almost be as complex as defining an interface. (An interface can define multiple methods, a syntax for declaring 1st class methods would only be for one method). You could think of this as a short form interface syntax. Under the hood the compiler could translate the short form notation to an interface at compile time.
There are a lot of things that could be done to Java to improve the Anonymous Class experience without ditching the language or major surgery.
As far as they both affect otherwise "private" scoping, in a very limited sense, yes. however, there are so many differences that the answer might as well be no.
Since Java lacks the ability to handle blocks of code as true R-values, inner classes cannot pass blocks of code as is typically done in continuations. Therefore the closure as a continuation technique is completely missing.
While the lifetime of a class to be garbage collected is extended by people holding inner classes (similar to closures keeping variables alive while being rebound to the closure), the ability of Java to do renaming via binding is limited to comply with the existing Java syntax.
And to allow threads to properly not stomp over each other's data using Java's thread contention model, inner classes are further restricted with access to data that is guaranteed not to upset, aka final locals.
This completely ignores the other inner classes (aka static inner classes) which is slightly different in feel. In other words, it touches upon a few items that closures could handle, but falls short of the minimum requirements that most people would consider necessary to be called a closure.
IMHO, They serve a similar purpose, however a closure is intended to be more concise and potentially provide more functionality.
Say you want to use a local variable using an anonymous class.
final int[] i = { 0 };
final double[] d = { 0.0 };
Runnable run = new Runnable() {
public void run() {
d[0] = i[0] * 1.5;
}
};
executor.submit(run);
Closures avoid the need for most of the boiler plate coding by allowing you write just what is intended.
int i = 0;
double d = 0.0;
Runnable run = { => d = i * 1.5; };
executor.submit(run);
or even
executor.submit({ => d = i * 1.5; });
or if closures support code blocks.
executor.submit() {
d = i * 1.5;
}

Categories