Explicit Java Validation

I have one thread1 :

 if(object != null){ object.play(); } 

and another thread2 , which can write a null link to object at any time.

I will run these threads at the same time. I know that thread2 can rewrite the object link after checking for null , and it will throw a NullPointerException . Is it possible for thread2 rewrite the object link after a NullPointerException to check?

+4
source share
7 answers

Is it possible for thread2 to rewrite an object reference after a NullPointerException?

Absolutely - this can change the value of object while the play() method is running, if that is what you mean. This would not cause an error in itself.

Note that without synchronization or other memory barriers, thread2 can change the value of object without notifying thread1 for an indefinite period of time.

It's hard to say what you should do without any other knowledge of the larger purpose of the code.

+6
source

A 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 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 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(); } } 
+5
source

Here you can use CountDownLatch . Where Thread1 will wait for Thread2 to count, and you can complete the task in thread2 and stop the count.

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(); } } } 
+1
source

If object is an instance variable or a static variable that can be changed from multiple threads, its value can vary between the time you check in the if and the time you call its instance method.

You can change the code to avoid this problem by copying the object to a local variable, for example:

 Playable objectCopy = object; if(objectCopy != null) { objectCopy.play(); } 

Since objectCopy is a local variable, its value cannot change between the test and the call to play . Of course, the state of the reproduced object may change, but this cannot be fixed by checking null .

+1
source

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

+1
source

To solve this problem you will need to use the synchronization primitive. See "Syncrhonised Statementments" here . In your case, you need to wrap the entire if block and any places in any threads that use or update object2 .

0
source

As my professor said: β€œConcurrency is a rather unstable guy. We never know what to expect from him.” To your question:

Is it possible for thread2 to rewrite an object reference after a NullPointerException?

Yes

Thread2 can access the object many times during 1 occurrence of thread1. Or vice versa. There may be many occurrences of thread1, and thread2 to the object.

If you use simple

System.out.println ();

in many places in your code, you may notice console output that will be displayed AFTER a NullPointerException error (if it has not been caught).

0
source

Source: https://habr.com/ru/post/1438403/


All Articles