I am well aware that it is not good practice to synchronize on Boolean.
There is a lot explanation why it's not good such as:
Why is it not a good practice to synchronize on Boolean?
http://telliott.io/node/40/
https://www.securecoding.cert.org/confluence/display/java/LCK01-J.+Do+not+synchronize+on+objects+that+may+be+reused
etc.
So, it is clear that this is BAD practice:
The code synchronizes on a boxed primitive constant, such as an
Boolean.
private static Boolean inited = Boolean.FALSE;
...
synchronized(inited)
{
if (!inited)
{
init();
inited = Boolean.TRUE;
}
}
...
What interests me is what happens if we create final static Boolean with "new" operator, i.e. someting like this (this is from real code I haven't wrote but I maintain it, names of methods etc. are changed):
private final static Boolean lock = new Boolean(true);
...
public static SomethingGeneric getSomething()
{
synchronized(lock)
{
if (somethingElse == null)
{
try
{
somethingElse = persistence.valueobject.getSomeValue(GET_THAT);
System.out.println("blah blah");
}
catch (ObjectCreationException oce)
{
// report the error
log.error("There was this and that error", oce);
System.out.println("Could not create it");
}
}
return somethingElse;
}
}
Would it be then "legal" to use it? Same as if we used Object such as in:
private final Object lock = new Object();
or
private static final Object lock = new Object();
public void doSomething() {
synchronized (lock) {
// ...
}
}
Thats fine. There are two problems with your first snippet, not that it is a Boolean but first, the object changes in this line:
inited = Boolean.TRUE;
So some threads can be synchronized on the old object and some on the new. This means, there is no synchronization between the two groups.
And second, Boolean.TRUE and Boolean.FALSE are global objects and if they are used in a similar way somewhere else this will create some hard to detect synchronisation problems (thanks to Mark Rotteveel for pointing it out).
You are synchronizing on the object reference. Creating private final Object lock = new Object(); would have the same effect as private final static Boolean lock = new Boolean(true);. All you want in this case is a unique object.
You should be careful though, because new Boolean(true) will create a new object reference. If you tried to use Boolean.TRUE or true they are in essence interned and will use the same instance, for example:
Boolean bool1 = new Boolean(true);
Boolean bool2 = Boolean.TRUE;
Boolean bool3 = true;
System.out.println(System.identityHashCode(bool1));
System.out.println(System.identityHashCode(bool2));
System.out.println(System.identityHashCode(bool3));
Will print
1433743869
19203296
19203296
So synchronizing on bool1 will be mutually exclusive to bool2 and bool3 but 2 & 3 will share exclusivity.
Note identityHashCode will give you the reference hash code, that tells you which objects are == equal.
Since new Boolean(true) != new Boolean(true), you can use such a lock.
Be careful though since Boolean.valueOf(true) == Boolean.valueOf(true).
All together if you are maintaining that code, just replace the lock with lock = new Object() as you suggest.
Since new Boolean(...) gives you a brand-new Object, the only difference between using new Boolean(...) and new Object() for your lock would be the fact that Boolean has a true or false value associated with it, while Object does not.
You can check that you get new objects from calling new Boolean(...) by running this code snippet:
Boolean bt = Boolean.TRUE;
Boolean bf = Boolean.FALSE;
for (int i = 0 ; i != 20 ; i++) {
Boolean b = new Boolean(i % 2 == 0);
System.out.println(b);
System.out.println("==true : "+(b==bt));
System.out.println("==false: "+(b==bf));
}
This prints
true
==true : false
==false: false
false
==true : false
==false: false
true
==true : false
==false: false
false
==true : false
==false: false
...
meaning that the objects you get are not the same as Boolean.TRUE and Boolean.FALSE.
Note: Although the practice appears completely harmless, I see no point in trying to synchronize on a Boolean, an Integer, a String, or any other immutable object, because it gives you no advantages over synchronizing on Object lock = new Object(), while not being as recognizable an idiom. This reflects on readability of your code, because programmers reading your code would be scratching their heads over your decision to lock on new Boolean(...).
Related
I have a java private method and I am trying to find the best way to create an object inside the method. Following are two different approaches that I am trying:
Approach A:
private void createObject() {
Object A;
if (conditionA) {
A = new Object();
//do some Action X with object A
} else {
//Do something without object A
if (conditionB) {
return;
}
A = new Object();
//do some Action Y with object A
}
return;
}
Approach B:
private void createObject() {
Object A = new Object()
if (conditionA) {
//do some action X with Object A
} else {
//Do something without Object A
if (conditionB) {
return;
}
//do some action Y with Object A
}
return;
}
Obviously both the code snippets are working and without any issues. I am just trying to find out the better coding style and standard.
Let's write the truth table
A | B | Expected Outcome
-----+-------+-------------------------------
True | True | do X with object A
True | False | do X with object A
False| False | do Y with object A
False| True | do something without object A
-----+-------+-------------------------------
I think this translates to:
boolean doXWithA = conditionA;
boolean doYWithA = !conditionA && !conditionB;
boolean doSomethingWithA = doXWithA || doYWithA;
if(doSomethingWithA)
Object a = new Object();
if (doXWithA) {
// do X with object A
} else if (doXWithB) {
// do X with object B
}
} else {
// do something without object A
}
Good practice is to reduce the scope of variables as much as possible. And if the instantiation is expensive, you also want to reduce the number of time you instantiate it.
Here Object a is only initialised when necessary and its scope is as small as possible (only one if block)
I believe that if you want to initialize object with default value you should do this in the place of declaration
Object A = new Object();
if (conditionA) {
...
}
Approach A is better.
In that, Consider "if" condition is not satisfied and it goes in "else".
There if conditionB is satisfied, then it will return.So memory is not allocated to A.
In Approach B, unnecessarily memory allocation is done which is of no use in above scenario.
I would go with approach A, as it is only necessary to initialize the object when needed.
If the initialization of that object is rather complicated, in order to avoid repeating yourself, you either define a static helper method in order to initialize the object or you go via a Supplier<>:
Supplier<Type> objSupplier = () -> new Type(a, b, c, d, whatever)
and then, at the two places where the object is supposed to be created, you do
A = objSupplier.get();
(note that variables are usually written in lowercase/camelCase).
I am trying to find the best way to write this method. One side we can assign a boolean variable with true and false value and return the value.
boolean methodName(..arguments)
{
boolean variableName=false;
if(..check condition)
{
variableName=false;
}
return variableName;
}
Another way is to return true or false directly without assigning it to any declared variable for example return true.
For simple methods that do not have many checks on the Boolean conditions, it's usually fine to simply return true or false.
boolean methodName(..arguments) {
return <checkCondition>
}
The above snippet is a reduction of your code's intent (I say intent because yours will always return false).
For more complex functions, a common rule of thumb is to assign a return variable, similar to what you've provided; having too many return statements can be harder to maintain.
This all said, it typically boils down to coding standards maintained by the software team.
You don't need to use any variables for return true or false value.
This simple method will be looks like this:
boolean yourMethod(argument) {
if (yourCondition)
return true;
else
return false;
}
or more simply (and more correct):
boolean yourMethod(argument) {
return (yourCondition);
}
For example. The user inputs word ("name" e.g.). And you need to check that he wrote exactly "name" using boolean method. Now you write this:
public static void main(String[] args) {
// We create input stream reader and read input data.
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
String s = reader.readLine();
// Now you check out that user wrote exactly your word ("name").
boolean result = checkInputData(s);
}
// Create boolean method.
static boolean checkInputData(String arg) {
return arg.equals("name");
}
And if the user had wrote "name", your variable result will be true. Else it will be false.
Either assigning the true or false value to a variable or returning true or false do pretty much the same thing. It depends on what makes sense in the scope of what's calling your method and how it's value is used.
Like the results from five.checkToSeeIfItsFive(); might make more sense when you read it if it's just returning true, vs. returning a variable that contains the value of true.
From Usage_in_Java & Effective Java 2, I do understand I need to have volatile keyword, if the lazy initialization target is a single variable.
However, what about I'm perform multiple lazy initialization, and store them in a ConcurrentHashMap? Does the Map need to be volatile too?
Here's the code example.
public class Utils {
private static final Map<Integer, RemoteViews> remoteViewsMap = new ConcurrentHashMap<Integer, RemoteViews>();
public static RemoteViews getRemoteViews(int resourceId) {
RemoteViews remoteViews = remoteViewsMap.get(resourceId);
if (remoteViews == null) {
synchronized(remoteViewsMap){
remoteViews = remoteViewsMap.get(resourceId);
if (remoteViews == null) {
remoteViews = new RemoteViews("org.yccheok.gui", resourceId);
remoteViewsMap.put(resourceId, remoteViews);
}
}
}
return remoteViews;
}
}
Is the above code correct and thread safe?
There's no need for volatile keyword since ConcurrentHashMap being an implementation of ConcurrentMap provides the following memory consistency effect:
actions in a thread prior to placing an object into a ConcurrentMap as a key or value happen-before actions subsequent to the access or removal of that object from the ConcurrentMap in another thread
However, that's not how you usually want to work with concurrent map. General pattern is as follows:
Object existing = concurrentMap.get(key);
// check if this key is already present
if (existing == null) {
Object newObject = new Object();
existing = concurrentMap.putIfAbsent(key, newObject); // atomic operation
// another thread might have already stored mapping for key
if (existing == null) {
return newObject;
}
}
return existing;
Note, it doesn't protect you from two threads simultaneously calling new Object() (which can be an issue if creation of new object is expensive), but it allows you to avoid explicit synchronization alltogether.
Update: as for double-checked locking, in your case, it should look as follows:
Object value = concurrentMap.get(key);
if (value == null) {
synchronized (lock) {
value = concurrentMap.get(key);
if (value == null) {
value = new Object();
concurrentMap.put(key, value);
}
}
}
return value;
Today, I've stumbled over the following:
Consider two classes NewClass and NewClass1, which have the following "equals"-methods:
NewClass:
#Override
public boolean equals(Object obj) {
return false;
}
public boolean equals(NewClass obj) {
return value == obj.getValue();
}
NewClass1:
#Override
public boolean equals(Object obj) {
if(!(obj instanceof NewClass1)) {
return false;
}
return equals((NewClass1) obj);
}
public boolean equals(NewClass1 obj) {
return value == obj.getValue();
}
What I find weird is that the equals in NewClass1 seems to be exponentially slower than the one in NewClass (for 10.000.000 calls 14ms against 3000ms). At first, I thought this was related to the "instanceof" check, but if I replace "return equals((NewClass1) obj);" with "return false;" in NewClass1, suddenly it runs more or less equally fast. I don't really understand what is happening here, because in my opinion, the return statement in equals(Object) should never actually be called. What am I getting wrong here?
The following is my "benchmarking code", in case I made some mistake there:
public static void main(String[] args) {
// TODO code application logic here
NewClass i1 = new NewClass(1);
NewClass i2 = new NewClass(1);
NewClass i3 = new NewClass(5);
NewClass1 j1 = new NewClass1(1);
NewClass1 j2 = new NewClass1(1);
NewClass1 j3 = new NewClass1(5);
Object o1 = new Object();
Object o2 = new Object();
assert(i1.equals(i1));
assert(i1.equals(i2));
assert(i1.equals(i3) == false);
assert(i1.equals(o1) == false);
assert(j1.equals(j1));
assert(j1.equals(j2));
assert(j1.equals(j3) == false);
assert(j1.equals(o1) == false);
long start = System.currentTimeMillis();
for(int i=0; i<1000000000; i++) {
i1.equals(i1);
i1.equals(i2);
i1.equals(o1);
i1.equals(o2);
}
long end = System.currentTimeMillis();
System.out.println("Execution time was "+(end-start)+" ms.");
start = System.currentTimeMillis();
for(int i=0; i<1000000000; i++) {
j1.equals(j1);
j1.equals(j2);
j1.equals(o1);
j1.equals(o2);
}
end = System.currentTimeMillis();
System.out.println("Execution time was "+(end-start)+" ms.");
}
I would guess that it is the instanceof test that is consuming the time. When you change the final return in that method to always return false, the compiler probably eliminates the conditional, since the result will be the same (return false) regardless of its evaluation. This would also explain why changing the final return has any effect at all, since as you say it should never actually be reached in the code path.
To put it more generally, a code change can impact performance even if it is not on the executed code path, by changing how the compiler optimizes the code.
In the first example equals(NewClass) would ordinarily never be called. equals(Object) can be inlined by HotSpot (or similar), and the body of your test can be reduced to effectively nothing.
Back of enveloper calculations can be informative. "10.000.000 calls 8ms" is 1,250,000,000 iterations a second. Assuming a 4 GHz processor, that's about three cycles per iteration. A bit fast to be doing anything worthwhile. In fact the code says 1,000,000,000 not 10,000,000.
In fact in the actual code all the loop body could be eliminated. So, it doesn't really matter what you are measuring - it wont be reliable indication of anything useful. There are many other problems with doing microbenchmarks, which you can read in many other places.
In the first example you always return false. This is very fast. In the second example you have a much longer comparison algorithm
Well, the first example does nearly nothing.. You can descrease the iteration number to 100000, again you get the same result, 5 or 6 ms. It means that JVM optimizes aggressively that part of your code.
Is there a better way to negate a boolean in Java than a simple if-else?
if (theBoolean) {
theBoolean = false;
} else {
theBoolean = true;
}
theBoolean = !theBoolean;
theBoolean ^= true;
Fewer keystrokes if your variable is longer than four letters
Edit: code tends to return useful results when used as Google search terms. The code above doesn't. For those who need it, it's bitwise XOR as described here.
There are several
The "obvious" way (for most people)
theBoolean = !theBoolean;
The "shortest" way (most of the time)
theBoolean ^= true;
The "most visual" way (most uncertainly)
theBoolean = theBoolean ? false : true;
Extra: Toggle and use in a method call
theMethod( theBoolean ^= true );
Since the assignment operator always returns what has been assigned, this will toggle the value via the bitwise operator, and then return the newly assigned value to be used in the method call.
This answer came up when searching for "java invert boolean function". The example below will prevent certain static analysis tools from failing builds due to branching logic. This is useful if you need to invert a boolean and haven't built out comprehensive unit tests ;)
Boolean.valueOf(aBool).equals(false)
or alternatively:
Boolean.FALSE.equals(aBool)
or
Boolean.FALSE::equals
If you use Boolean NULL values and consider them false, try this:
static public boolean toggle(Boolean aBoolean) {
if (aBoolean == null) return true;
else return !aBoolean;
}
If you are not handing Boolean NULL values, try this:
static public boolean toggle(boolean aBoolean) {
return !aBoolean;
}
These are the cleanest because they show the intent in the method signature, are easier to read compared to the ! operator, and can be easily debugged.
Usage
boolean bTrue = true
boolean bFalse = false
boolean bNull = null
toggle(bTrue) // == false
toggle(bFalse) // == true
toggle(bNull) // == true
Of course, if you use Groovy or a language that allows extension methods, you can register an extension and simply do:
Boolean b = false
b = b.toggle() // == true
The class BooleanUtils supportes the negation of a boolean. You find this class in commons-lang:commons-lang
BooleanUtils.negate(theBoolean)
Boolean original = null; // = Boolean.FALSE; // = Boolean.TRUE;
Boolean inverse = original == null ? null : !original;
If you're not doing anything particularly professional you can always use a Util class. Ex, a util class from a project for a class.
public class Util {
public Util() {}
public boolean flip(boolean bool) { return !bool; }
public void sop(String str) { System.out.println(str); }
}
then just create a Util object
Util u = new Util();
and have something for the return System.out.println( u.flip(bool) );
If you're gonna end up using the same thing over and over, use a method, and especially if it's across projects, make a Util class. Dunno what the industry standard is however. (Experienced programmers feel free to correct me)
Before:
boolean result = isresult();
if (result) {
result = false;
} else {
result = true;
}
After:
boolean result = isresult();
result ^= true;