Java null check - java

I have one thread1:
if(object != null){
object.play();
}
and another thread2 that can write null into object reference at any time.
I will run these threads at same time. I know thread2 can rewrite object reference after the null check and that will throw NullPointerException. Is it possible for thread2 to rewrite object reference after NullPointerException check?

Is it possible to for thread2 to rewrite object reference after NullPointerException check ?
Absolutely - it could change the value of object while the play() method is executing, if that's what you mean. That wouldn't cause an error in itself.
Note that without synchronization or other memory barriers, thread2 could change the value of object without thread1 noticing for an indeterminate period of time.
It's hard to say what you ought to do, without any other knowledge of the bigger aim of the code.

Simple synchronized example:
/**
To maintain thread safety, only access this through getter and setter
or other synchronized method
**/
private ObjectType object;
public synchronized void setObject(ObjectType object) {
this.object = object;
}
public synchronized ObjectType getObject() {
return object;
}
public void doPlay() {
final ObjectType obj = getObject();
//here, thread 2 can change "object", but it's not going to affect this thread
//as we already safely got our reference to "object" in "obj".
if(obj != null){
obj.play();
}
}
public synchronized void alterativeDoPlay() {
//the difference here is that another thread won't be able to change "object"
//until the object's play() method has completed.
//depending on the code in play, this has potential for deadlocks, where as
//the other `doPlay` has zero deadlock potential.
if(object != null){
object.play();
}
}

If object is an instance variable or a static variable that can be changed from multiple threads, its value can change between the time you test it in the if statement and the time when you call its instance method.
You can modify the code to avoid this problem by copying the object into a local variable, like this:
Playable objectCopy = object;
if(objectCopy != null) {
objectCopy.play();
}
Since objectCopy is a local variable, its value cannot change between the test and the call of play. Of course the state of the playable object itself can change, but that is not something that can be fixed by null checking.

You can use CountDownLatch here. Where Thread1 will wait to count down by Thread2 and you can perform the task in thread2 and stop count down.
Code snippet -
CountDownLatch latch = new CountDownLatch(1);
new Thread1(latch).start();
new Thread2(latch).start();
public class Thread1 extends Thread {
private final CountDownLatch startLatch;
public Thread1(CountDownLatch startLatch) {
this.startLatch = startLatch;
}
public void run() {
try {
startLatch.await();
// ... perform task
} catch (InterruptedException iex) {}
}
}
public class Thread1 extends Thread {
private final CountDownLatch stopLatch;
public Thread1(CountDownLatch stopLatch) {
this.stopLatch = stopLatch;
}
public void run() {
try {
// perform task
} finally {
stopLatch.countDown();
}
}
}

According to Brian's Law :
When we write a variable, which next has to be read by another thread, or when we are reading a variable which has lately been written by another thread, then use synchronization.
Synchronize the atomic statements or getter/setters which has access to the crucial state of data with the same monitor lock.
- Use synchronization.
- You can use CountDownLatch from java.util.concurrent

You will need to use some form of synchronisation primitive to solve this problem. See "Syncrhonised Statements" here. In your case you will need to wrap the whole if block and any places in any threads that use or update object2.

As my professor said: "Concurrency is a pretty unstable guy. We never know what to expect of him." Comming to your question:
Is it possible for thread2 to rewrite object reference after
NullPointerException check?
Yes
Thread2 can access the object many times during 1 occurrence of thread1. Or the other way around. There may be many occurrences of thread1, while thread2 accesses the object.
If you use simple
System.out.println();
in many places in your code, you may notice the output in the console to be displayed AFTER the NullPointerException error(if it wasn't caught).

Related

Synchronizing on AtomicBoolean?

In an application I'm working on I found the following code snippet:
public class MyClass {
private AtomicBoolean atomicBoolean = new AtomicBoolean(false);
public void Execute() {
// Whole lot of business logic
// ....
synchronized (this.atomicBoolean) {
// Want to make sure that execution is stopped if Stop() was called
if (this.atomicBoolean.get()) {
throw new SpecificException("...");
}
// Some more business logic...
}
}
public void Stop() {
synchronized (this.atomicBoolean) {
this.atomicBoolean.set(true);
}
}
}
According to FindBugs this is not correct as I can't use an AtomicBoolean together with synchronized and expect it to block the object.
My question is: What is the correct way to rewrite this methods? I've read about using an lock Object together with a boolean attribute instead but it appears kinda clumsy to introduce two new attributes for this lock.
Edit: As stated in a comment below: I think the intention is that in the two synchronized blocks, the AtomicBoolean can't be changed and that while one Thread is in one of the synchronized blocks, none other such block could be entered.
just replace the synchronized (this.atomicBoolean) { part from both methods, AtomicBoolean::get and AtomicBoolean::set is already atomic.
...I can't use an AtomicBoolean together with synchronized...
For whatever it's worth, the language allows you to synchronize on any object.
As a matter of style, some programmers prefer to only synchronize on a private object that is used for no other purpose.
private static Object foobarLock = new Object();
...
public void fooItUp(...) {
...
synchronized(foobarLock) {
...
}
...
}
...and expect it to block the object
Just to be clear, when some thread T enters a synchronized (o) {...} block, that does not prevent other threads from accessing or modifying the object o. The only thing it prevents is, it prevents some other thread U from entering a synchronized block on the same object o at the same time.

synchronized block : "expression expected"

When I use the code shown below, IntelliJ IDEA tell me "expression expected" in the code DecibelSample. What is that mean, How can I fix it?
if (mDecibelSample == null) {
synchronized (DecibelSample) { // expression expected
if (mDecibelSample == null) {
mDecibelSample = new DecibelSample();
}
}
}
Assuming that DecibelSample is a class, this is not valid Java code.
Modify your code like this in order to get rid of the compile error:
synchronized (DecibelSample.class) {}
Your code won't work because synchronized needs some instance to lock against. In the modified example above it will use the Class instance.
You could also change it to synchronized (this) {} in which case it would use the instance of the class your method is in as the lock.
Third option is to define arbitrary object to use as a lock, for instance like this:
private static final Object LOCK = new Object();
...
public void foo() {
synchronized(LOCK) {}
}
This would probably be the best approach, since locking against the current instance or class instance has some disadvantages. See this SO answer for more details:
More information about the synchronized keyword can be found in Java Language Specification.
The synchronized keyword requires an Object. DecibelSample is a classname, not an Object.
The Object will be used to ensure synchronization : i.e. when a thread need to execute the code inside the synchronized block : the thread must acquire a lock on the Object.
if the lock can be aquired by the thread then the code inside the block is executed and the lock is released so that another thread can acquire it.
if the lock cannot be acquired : the thread wait until the lock (owned by another thread) is released.
In your case, you need an Object to support the locking mechanism:
//used for locking only
// don't consume useless memory : a zero-sized array is fine
// ensure that the LOCK is shared between all threads : let's make it static
// ensure that the object used for locking cannot be changed by anyone : let's make it final
// at first sight : we don't need to synchronize on this Object in another class : keep it private.
private static final Object[] LOCK = new Object[0];
...
if (mDecibelSample == null) {
synchronized (LOCK) {
if (mDecibelSample == null) {
mDecibelSample = new DecibelSample();
}
}
}

Synchronizing static variables

What I understand by synchronizing static object which is a variable, if one thread is accessing it, other thread can't.
class T3
{
static Integer i = 0;
static void callStatic()
{
synchronized(T3.class)
{
System.out.println(i++);
while(true);
}
}
public void notStatic()
{
System.out.println(i++);
while(true);
}
}
class T2 implements Runnable
{
public void run()
{
System.out.println("calling nonstatic");
new T3().notStatic();
}
}
class T implements Runnable
{
public void run()
{
System.out.println("calling static");
T3.callStatic();
}
}
public class Test
{
public static void main(String[] args)
{
new Thread(new T()).start();
try
{
Thread.sleep(100);
}
catch (InterruptedException e)
{
}
new Thread(new T2()).start();
}
}
But this demo program has output as :
calling static
0
calling nonstatic
1
Is my understanding wrong? Or am I missing something?
I tried, synchronzing callStatic method, and synchronizing T3.class class object too. But none worked as I thought.
Note : I thought, 1 will not be printed as callStatic has lock on variable i and is in infinite loop.
You don't synchronize on variables, you synchronize on objects.
callStatic synchronizes on 1 and then sets i to 2. If notStatic were to enter a synchronized(i) block at this point, it would synchronize on 2. No other thread has locked 2, so it proceeds.
(Actually, 1 and 2 aren't objects, but Integer.valueOf(1) and Integer.valueOf(2) return objects, and the compiler automatically inserts the Integer.valueOf calls to convert ints to Integers)
In your code, notStatic doesn't actually synchronize at all. It's true that only one thread can be in a synchronized block for a particular object at a particular time, but that has no effect on other threads that are not trying to enter a synchronized block.
Note: This answer relates to the original question, which had synchronized(i), not synchronized(T3.class), in callStatic. The edit really changes the question.
synchronize acts on the object, not the variable/member holding it. There are a couple of important things going on in your code.
synchronize(i) does indeed synchronize access to i provided that the other code trying to use it also synchronizes. It has no effect on code that doesn't synchronize. Suppose Thread A does synchronize(i) and holds it (your infinite loop); then Thread B does System.out.println(i); Thread B can happily read i, there's nothing stopping it. Thread B would have to do
synchronize (i) {
System.out.println(i);
}
...in order to be affected by Thread A's synchronize(i). Your code is (attempting to) synchronized mutation, but not access.
i++; with an Integer is effectively equivalent to i = new Integer(i.intValue() + 1), because Integer is immutable. So it creates a different Integer object and stores that in the i member. So anything synchronizing on the old Integer object has no effect on code synchronizing on the new one. So even if your code were synchronizing both access and mutation, it wouldn't matter, because the synch would be on the old object.
This means that the code in your callStatic is synchronizing on an instance of Integer and then repeated creating a bunch of other instances, which it is not synchronizing on.
Synchronized blocks on static and non static don't block each other. You need to understand how synchronized works for this. Synchronized is done always on an object never on a variable. When you synchronize, thread takes a lock on the object's monitor, the object which you put in the synchronized statement braces.
Synchronized blocks on static references (like in your code) lock on the .class object of your class and not on any instance of that class. So static and non-static synchronized blocks don't block each other.
Now in your code the notStatic method doesn't synchronize on anything where as the callStatic synchronizes on the static i Integer object. So they don't block each other.

Synchronization of non-final field

A warning is showing every time I synchronize on a non-final class field. Here is the code:
public class X
{
private Object o;
public void setO(Object o)
{
this.o = o;
}
public void x()
{
synchronized (o) // synchronization on a non-final field
{
}
}
}
so I changed the coding in the following way:
public class X
{
private final Object o;
public X()
{
o = new Object();
}
public void x()
{
synchronized (o)
{
}
}
}
I am not sure the above code is the proper way to synchronize on a non-final class field. How can I synchronize a non final field?
First of all, I encourage you to really try hard to deal with concurrency issues on a higher level of abstraction, i.e. solving it using classes from java.util.concurrent such as ExecutorServices, Callables, Futures etc.
That being said, there's nothing wrong with synchronizing on a non-final field per se. You just need to keep in mind that if the object reference changes, the same section of code may be run in parallel. I.e., if one thread runs the code in the synchronized block and someone calls setO(...), another thread can run the same synchronized block on the same instance concurrently.
Synchronize on the object which you need exclusive access to (or, better yet, an object dedicated to guarding it).
It's really not a good idea - because your synchronized blocks are no longer really synchronized in a consistent way.
Assuming the synchronized blocks are meant to be ensuring that only one thread accesses some shared data at a time, consider:
Thread 1 enters the synchronized block. Yay - it has exclusive access to the shared data...
Thread 2 calls setO()
Thread 3 (or still 2...) enters the synchronized block. Eek! It think it has exclusive access to the shared data, but thread 1 is still furtling with it...
Why would you want this to happen? Maybe there are some very specialized situations where it makes sense... but you'd have to present me with a specific use case (along with ways of mitigating the sort of scenario I've given above) before I'd be happy with it.
I agree with one of John's comment: You must always use a final lock dummy while accessing a non-final variable to prevent inconsistencies in case of the variable's reference changes. So in any cases and as a first rule of thumb:
Rule#1: If a field is non-final, always use a (private) final lock dummy.
Reason #1: You hold the lock and change the variable's reference by yourself. Another thread waiting outside the synchronized lock will be able to enter the guarded block.
Reason #2: You hold the lock and another thread changes the variable's reference. The result is the same: Another thread can enter the guarded block.
But when using a final lock dummy, there is another problem: You might get wrong data, because your non-final object will only be synchronized with RAM when calling synchronize(object). So, as a second rule of thumb:
Rule#2: When locking a non-final object you always need to do both: Using a final lock dummy and the lock of the non-final object for the sake of RAM synchronisation. (The only alternative will be declaring all fields of the object as volatile!)
These locks are also called "nested locks". Note that you must call them always in the same order, otherwise you will get a dead lock:
public class X {
private final LOCK;
private Object o;
public void setO(Object o){
this.o = o;
}
public void x() {
synchronized (LOCK) {
synchronized(o){
//do something with o...
}
}
}
}
As you can see I write the two locks directly on the same line, because they always belong together. Like this, you could even do 10 nesting locks:
synchronized (LOCK1) {
synchronized (LOCK2) {
synchronized (LOCK3) {
synchronized (LOCK4) {
//entering the locked space
}
}
}
}
Note that this code won't break if you just acquire an inner lock like synchronized (LOCK3) by another threads. But it will break if you call in another thread something like this:
synchronized (LOCK4) {
synchronized (LOCK1) { //dead lock!
synchronized (LOCK3) {
synchronized (LOCK2) {
//will never enter here...
}
}
}
}
There is only one workaround around such nested locks while handling non-final fields:
Rule #2 - Alternative: Declare all fields of the object as volatile. (I won't talk here about the disadvantages of doing this, e.g. preventing any storage in x-level caches even for reads, aso.)
So therefore aioobe is quite right: Just use java.util.concurrent. Or begin to understand everything about synchronisation and do it by yourself with nested locks. ;)
For more details why synchronisation on non-final fields breaks, have a look into my test case: https://stackoverflow.com/a/21460055/2012947
And for more details why you need synchronized at all due to RAM and caches have a look here: https://stackoverflow.com/a/21409975/2012947
I'm not really seeing the correct answer here, that is, It's perfectly alright to do it.
I'm not even sure why it's a warning, there is nothing wrong with it. The JVM makes sure that you get some valid object back (or null) when you read a value, and you can synchronize on any object.
If you plan on actually changing the lock while it's in use (as opposed to e.g. changing it from an init method, before you start using it), you have to make the variable that you plan to change volatile. Then all you need to do is to synchronize on both the old and the new object, and you can safely change the value
public volatile Object lock;
...
synchronized (lock) {
synchronized (newObject) {
lock = newObject;
}
}
There. It's not complicated, writing code with locks (mutexes) is actally quite easy. Writing code without them (lock free code) is what's hard.
EDIT: So this solution (as suggested by Jon Skeet) might have an issue with atomicity of implementation of "synchronized(object){}" while object reference is changing. I asked separately and according to Mr. erickson it is not thread safe - see: Is entering synchronized block atomic?. So take it as example how to NOT do it - with links why ;)
See the code how it would work if synchronised() would be atomic:
public class Main {
static class Config{
char a='0';
char b='0';
public void log(){
synchronized(this){
System.out.println(""+a+","+b);
}
}
}
static Config cfg = new Config();
static class Doer extends Thread {
char id;
Doer(char id) {
this.id = id;
}
public void mySleep(long ms){
try{Thread.sleep(ms);}catch(Exception ex){ex.printStackTrace();}
}
public void run() {
System.out.println("Doer "+id+" beg");
if(id == 'X'){
synchronized (cfg){
cfg.a=id;
mySleep(1000);
// do not forget to put synchronize(cfg) over setting new cfg - otherwise following will happend
// here it would be modifying different cfg (cos Y will change it).
// Another problem would be that new cfg would be in parallel modified by Z cos synchronized is applied on new object
cfg.b=id;
}
}
if(id == 'Y'){
mySleep(333);
synchronized(cfg) // comment this and you will see inconsistency in log - if you keep it I think all is ok
{
cfg = new Config(); // introduce new configuration
// be aware - don't expect here to be synchronized on new cfg!
// Z might already get a lock
}
}
if(id == 'Z'){
mySleep(666);
synchronized (cfg){
cfg.a=id;
mySleep(100);
cfg.b=id;
}
}
System.out.println("Doer "+id+" end");
cfg.log();
}
}
public static void main(String[] args) throws InterruptedException {
Doer X = new Doer('X');
Doer Y = new Doer('Y');
Doer Z = new Doer('Z');
X.start();
Y.start();
Z.start();
}
}
AtomicReference suits for your requirement.
From java documentation about atomic package:
A small toolkit of classes that support lock-free thread-safe programming on single variables. In essence, the classes in this package extend the notion of volatile values, fields, and array elements to those that also provide an atomic conditional update operation of the form:
boolean compareAndSet(expectedValue, updateValue);
Sample code:
String initialReference = "value 1";
AtomicReference<String> someRef =
new AtomicReference<String>(initialReference);
String newReference = "value 2";
boolean exchanged = someRef.compareAndSet(initialReference, newReference);
System.out.println("exchanged: " + exchanged);
In above example, you replace String with your own Object
Related SE question:
When to use AtomicReference in Java?
If o never changes for the lifetime of an instance of X, the second version is better style irrespective of whether synchronization is involved.
Now, whether there's anything wrong with the first version is impossible to answer without knowing what else is going on in that class. I would tend to agree with the compiler that it does look error-prone (I won't repeat what the others have said).
Just adding my two cents: I had this warning when I used component that is instantiated through designer, so it's field cannot really be final, because constructor cannot takes parameters. In other words, I had quasi-final field without the final keyword.
I think that's why it is just warning: you are probably doing something wrong, but it might be right as well.

Java - threads + action

I'm new to Java so I have a simple question that I don't know where to start from -
I need to write a function that accepts an Action, at a multi-threads program , and only the first thread that enter the function do the action, and all the other threads wait for him to finish, and then return from the function without doing anything.
As I said - I don't know where to begin because,
first - there isn't a static var at the function (static like as in c / c++ ) so how do I make it that only the first thread would start the action, and the others do nothing ?
second - for the threads to wait, should I use
public synchronized void lala(Action doThis)
{....}
or should i write something like that inside the function
synchronized (this)
{
...
notify();
}
Thanks !
If you want all threads arriving at a method to wait for the first, then they must synchronize on a common object. It could be the same instance (this) on which the methods are invoked, or it could be any other object (an explicit lock object).
If you want to ensure that the first thread is the only one that will perform the action, then you must store this fact somewhere, for all other threads to read, for they will execute the same instructions.
Going by the previous two points, one could lock on this 'fact' variable to achieve the desired outcome
static final AtomicBoolean flag = new AtomicBoolean(false); // synchronize on this, and also store the fact. It is static so that if this is in a Runnable instance will not appear to reset the fact. Don't use the Boolean wrapper, for the value of the flag might be different in certain cases.
public void lala(Action doThis)
{
synchronized (flag) // synchronize on the flag so that other threads arriving here, will be forced to wait
{
if(!flag.get()) // This condition is true only for the first thread.
{
doX();
flag.set(true); //set the flag so that other threads will not invoke doX.
}
}
...
doCommonWork();
...
}
If you're doing threading in any recent version of Java, you really should be using the java.util.concurrent package instead of using Threads directly.
Here's one way you could do it:
private final ExecutorService executor = Executors.newCachedThreadPool();
private final Map<Runnable, Future<?>> submitted
= new HashMap<Runnable, Future<?>>();
public void executeOnlyOnce(Runnable action) {
Future<?> future = null;
// NOTE: I was tempted to use a ConcurrentHashMap here, but we don't want to
// get into a possible race with two threads both seeing that a value hasn't
// been computed yet and both starting a computation, so the synchronized
// block ensures that no other thread can be submitting the runnable to the
// executor while we are checking the map. If, on the other hand, it's not
// a problem for two threads to both create the same value (that is, this
// behavior is only intended for caching performance, not for correctness),
// then it should be safe to use a ConcurrentHashMap and use its
// putIfAbsent() method instead.
synchronized(submitted) {
future = submitted.get(action);
if(future == null) {
future = executor.submit(action);
submitted.put(action, future);
}
}
future.get(); // ignore return value because the runnable returns void
}
Note that this assumes that your Action class (I'm assuming you don't mean javax.swing.Action, right?) implements Runnable and also has a reasonable implementation of equals() and hashCode(). Otherwise, you may need to use a different Map implementation (for example, IdentityHashMap).
Also, this assumes that you may have multiple different actions that you want to execute only once. If that's not the case, then you can drop the Map entirely and do something like this:
private final ExecutorService executor = Executors.newCachedThreadPool();
private final Object lock = new Object();
private volatile Runnable action;
private volatile Future<?> future = null;
public void executeOnlyOnce(Runnable action) {
synchronized(lock) {
if(this.action == null) {
this.action = action;
this.future = executor.submit(action);
} else if(!this.action.equals(action)) {
throw new IllegalArgumentException("Unexpected action");
}
}
future.get();
}
public synchronized void foo()
{
...
}
is equivalent to
public void foo()
{
synchronized(this)
{
...
}
}
so either of the two options should work. I personally like the synchronized method option.
Synchronizing the whole method can sometimes be overkill if there is only a certain part of the code that deals with shared data (for example, a common variable that each thread is updating).
Best approach for performance is to only use the synchronized keyword just around the shared data. If you synchronized the whole method when it is not entirely necessarily then a lot of threads will be waiting when they can still do work within their own local scope.
When a thread enters the synchronize it acquires a lock (if you use the this object it locks on the object itself), the other will wait till the lock-acquiring thread has exited. You actually don't need a notify statement in this situation as the threads will release the lock when they exit the synchronize statement.

Categories

Resources