Can the below program crash? - java

For example, there is a piece of Java code, Home is a Java class, mHome can be a member in any object:
if((mHome != null) && (mHome.mName == "xxx"))
{ ...... }
My question is here. Is that possible that Home ref is null when running the condition Home.mName == "xxx". For example, after running the statement Home != null, the thread is switch out, and another thread put Home to be null.

With the amount of code that you have given, it is hard to say whether this piece will fail or not. For example,
public test(){
Home home = ...//call the constructor of home to create an instance
if(null!=home && home.mName=="xxx") {// bad comparison of string and bad way to access an instance variable
//some code
}
}
in the above case the comparison home.mName=="xxx"will not fail(result in null that is), as home is local to the method.
But
public test() {
// assuming home is an instance variable
if(null!=this.getHome() && this.getHome().mName=="xxx") {// bad comparison of string and bad way to access an instance variable
//some code
}
}
}
chances are there when
-> a thread A has completed executing null!=home
-> A is put to sleep
-> Another thread B changes the value of the variable home to null
-> Thread B is put to sleep
-> A resumes execution
-> NullPointerException
if the latter was the case then, you should make sure that the method accessing the value of the variable home is synchronized(thread safe basically). But it is a little tricky to understand synchronization. For example,
public class WrongThreadSafety {
private static String s;
public synchronized String setString(String s) {
this.s = s;
}
public synchronized String getStringLength() {
return s.length();
}
}
Though the above class has methods that are synchronized, it is really not thread safe. the method setString and getStringLength are thread-safe individually. That is two threads cannot access the method setString or getStringLength at the same time, but nothing is stopping a thread from calling the setString method with a null, and at the same time another thread calling the getStringLength method.

The direct answer to your question is ==> yes it is possible.
You need to make your code threadsafe . For that use synchronization
Here is a sample code employing synchronization from the link http://www.jguru.com/faq/view.jsp?EID=124425
package com.jgk.patterns.singleton;
public class JGKSingleton {
/* Here is the instance of the Singleton */
private static JGKSingleton instance_;
/* Need the following object to synchronize */
/* a block */
private static Object syncObject_;
/* Prevent direct access to the constructor
private JGKSingleton() {
super();
}
public static JGKSingleton getInstance() {
/* in a non-thread-safe version of a Singleton */
/* the following line could be executed, and the */
/* thread could be immediately swapped out */
if (instance_ == null) {
synchronized(syncObject_) {
if (instance_ == null) {
instance_ = new JGKSingleton();
}
}
}
return instance_;
}
}
This below link from stackoverflow shows how this issue is tackled in different ways.
Java null check

DISCLAIMER: I don't code java, but the question is more of a general multithreading question and so the answer should apply to java as well.
As you clearly understand, a different thread with access to Home can change anything, and if a context switch happens "between" the 2 parts of the if statement and it will fail.
There is a way to protect your code from this risk WITHOUT applying locking / synchronization methods and that is by grabbing a local reference (using a private variable) before the if statement and then you know for sure that if the variable isn't null, it's safe to access it's members. (*Note: This is only true in a garbage collecting environment, in C++ for example you might end up holding a reference to a deleted object and that will crash too).

Case 1: mHome has a local scope i.e. mHome is method argument or mHome is defined inside the method
No, variable will not be visible to other threads hence can not have two different values in the provided statement
Case 2: mHome is an instance variable, If mHome is an instance variable and you have scenarios where the given statement can be executed by multiple Threads, then there is a possibility that the two statements i.e. the null check and equality check can see different values. In such case you need to use synchronized keyword to create a critical section where only one thread can enter at a time

Related

Why would I check in a Runnable, that its Thread is not null?

I've found code like this in a project I'm taking over. I'm not sure, what the if condition is supposed to accomplish. If the Runnable is running, it does so in the Thread it checks for being null. So that is always the case, right?
public class Outer
{
Thread m_thread = null;
public Outer()
{
Runnable runner = new Runnable()
{
public void run()
{
if ( m_thread != null )
do_stuff();
}
};
m_thread = new Thread(runner);
m_thread.start();
}
}
There is actually another method, that sets m_thread to null, but since there is no loop in the runnable, does that make a difference? do_stuff() does not access m_thread.
Since m_thread is not marked volatile or guarded by any other memory barrier operation it's possible that when Runnable is running it will observe m_thread to be null. If do_stuff() requires non-null reference to m_thread, the code will fail.
Check the Safe Publication and Safe Initialization in Java article by Shipilev to understand safe publication idioms in Java. In short:
There are a few trivial ways to achieve safe publication:
Exchange the reference through a properly locked field (JLS 17.4.5)
Use static initializer to do the initializing stores (JLS 12.4)
Exchange the reference via a volatile field (JLS 17.4.5), or as the consequence of this rule, via the AtomicX classes
Initialize the value into a final field (JLS 17.5).
You don't. There was a fashion 20 years ago, that I think may have originated in a magazine, for run() methods to loop while (Thread.currentThread() != null). It was meaningless then and it is meaningless now, even when slightly re-expressed as in your code.
Simply spoken: that doesn't make any sense. When a line of code is executed in Java, some thread is running it.
Unless you start implementing your own tracking of threads, the fact that your code is running ... tells it that some thread is running it.
The code shown here A) violates Java naming conventions, and it also B) violates "common sense" in Java.
You see, you could still write code that first initializes that m_thread field, to then invoke runner.run() directly from the "main" thread. And the run method would find that the field is not null, and invoke doStuff(). If at all, you could check that Thread.getCurrentThread() returns something else than your "main" thread.
As in:
class Outer {
private Thread mainThread;
public Outer()
{
mainThread = Thread.getCurrentThread();
Runnable runner = new Runnable()
{
public void run()
{
if ( Thread.getCurrentThread() != mainThread )
do_stuff();
}
};
m_thread = new Thread(runner);
m_thread.start();
}
( I didn't run the above through the compiler, it is meant as "pseudo code like" example, not necessarily 100% correct )

Java lazy thread safe singleton with implemented with final field

I do not understand why local variable is needed here:
public class FinalWrapper<T> {
public final T value;
public FinalWrapper(T value) {
this.value = value;
}
}
public class Foo {
private FinalWrapper<Helper> helperWrapper;
public Helper getHelper() {
FinalWrapper<Helper> tempWrapper = helperWrapper;
if (tempWrapper == null) {
synchronized(this) {
if (helperWrapper == null) {
helperWrapper = new FinalWrapper<Helper>(new Helper());
}
tempWrapper = helperWrapper;
}
}
return tempWrapper.value;
}
}
I get this code from: https://en.wikipedia.org/wiki/Double-checked_locking#Usage_in_Java. What issues can we have if we do not have this local variable? According to the wiki article:
Semantics of final field in Java 5 can be employed to safely publish the helper object without using volatile. The local variable tempWrapper is required for correctness: simply using helperWrapper for both null checks and the return statement could fail due to read reordering allowed under the Java Memory Model. Performance of this implementation is not necessarily better than the volatile implementation.
Thanks in advance.
To understand the underlying issue let's remove the local variable from the code:
public class Foo {
private FinalWrapper<Helper> helperWrapper;
public Helper getHelper() {
if (helperWrapper == null) {
synchronized(this) {
if (helperWrapper == null) {
helperWrapper = new FinalWrapper<Helper>(new Helper());
}
}
}
return helperWrapper.value;
}
}
We have three reads in this case:
The outer null check.
The inner null check.
The read before the return.
The problem is that due to the read reordering the first read can return a non-null value and the third read can return null. It means that the third read happens before the first one, which is supposed to ensure helperWrapper is initialized...
Adding the local variable solves the issue because we assign helperWrapper value to tempWrapper and then it does not matter in what order tempWrapper is read. If it has a non-null value it is used both for the null check and for the return statement.
It can happen because Java Memory Model allows for such reordering of operations just for the optimization purpose. Look at the quote from here:
What is meant by reordering?
There are a number of cases in which accesses to program variables
(object instance fields, class static fields, and array elements) may
appear to execute in a different order than was specified by the
program. The compiler is free to take liberties with the ordering of
instructions in the name of optimization. Processors may execute
instructions out of order under certain circumstances. Data may be
moved between registers, processor caches, and main memory in
different order than specified by the program.
[...]
The compiler, runtime, and hardware are supposed to conspire to create
the illusion of as-if-serial semantics, which means that in a
single-threaded program, the program should not be able to observe the
effects of reorderings. However, reorderings can come into play in
incorrectly synchronized multithreaded programs, where one thread is
able to observe the effects of other threads, and may be able to
detect that variable accesses become visible to other threads in a
different order than executed or specified in the program.
[...]

Java null check

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).

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.

How do I create a thread-safe write-once read-many value in Java?

This is a problem I encounter frequently in working with more complex systems and which I have never figured out a good way to solve. It usually involves variations on the theme of a shared object whose construction and initialization are necessarily two distinct steps. This is generally because of architectural requirements, similar to applets, so answers that suggest I consolidate construction and initialization are not useful. The systems have to target Java 4 at the latest, so answers that suggest support available only in later JVMs are not useful either.
By way of example, let's say I have a class that is structured to fit into an application framework like so:
public class MyClass
{
private /*ideally-final*/ SomeObject someObject;
MyClass() {
someObject=null;
}
public void startup() {
someObject=new SomeObject(...arguments from environment which are not available until startup is called...);
}
public void shutdown() {
someObject=null; // this is not necessary, I am just expressing the intended scope of someObject explicitly
}
}
I can't make someObject final since it can't be set until startup() is invoked. But I would really like it to reflect its write-once semantics and be able to directly access it from multiple threads, preferably avoiding synchronization.
The idea being to express and enforce a degree of finalness, I conjecture that I could create a generic container, like so (UPDATE - corrected threading sematics of this class):
public class WormRef<T>
{
private volatile T reference; // wrapped reference
public WormRef() {
reference=null;
}
public WormRef<T> init(T val) {
if(reference!=null) { throw new IllegalStateException("The WormRef container is already initialized"); }
reference=val;
return this;
}
public T get() {
if(reference==null) { throw new IllegalStateException("The WormRef container is not initialized"); }
return reference;
}
}
and then in MyClass, above, do:
private final WormRef<SomeObject> someObject;
MyClass() {
someObject=new WormRef<SomeObject>();
}
public void startup() {
someObject.init(new SomeObject(...));
}
public void sometimeLater() {
someObject.get().doSomething();
}
Which raises some questions for me:
Is there a better way, or existing Java object (would have to be available in Java 4)?
Secondarily, in terms of thread safety:
Is this thread-safe provided that no other thread accesses someObject.get() until after its set() has been called. The other threads will only invoke methods on MyClass between startup() and shutdown() - the framework guarantees this.
Given the completely unsynchronized WormReference container, it is ever possible under either JMM to see a value of object which is neither null nor a reference to a SomeObject? In other words, does the JMM always guarantee that no thread can observe the memory of an object to be whatever values happened to be on the heap when the object was allocated. I believe the answer is "Yes" because allocation explicitly zeroes the allocated memory - but can CPU caching result in something else being observed at a given memory location?
Is it sufficient to make WormRef.reference volatile to ensure proper multithreaded semantics?
Note the primary thrust of this question is how to express and enforce the finalness of someObject without being able to actually mark it final; secondary is what is necessary for thread-safety. That is, don't get too hung up on the thread-safety aspect of this.
I would start by declaring your someObject volatile.
private volatile SomeObject someObject;
Volatile keyword creates a memory barrier, which means separate threads will always see updated memory when referencing someObject.
In your current implementation some threads may still see someObject as null even after startup has been called.
Actually this volatile technique is used a lot by collections declared in java.util.concurrent package.
And as some other posters suggest here, if all else fails fall back to full synchronization.
I would remove the setter method in WoRmObject, and provide a synchronised init() method which throws an exception if (object != null)
Consider using AtomicReference as a delegate in this object-container you're trying to create. For example:
public class Foo<Bar> {
private final AtomicReference<Bar> myBar = new AtomicReference<Bar>();
public Bar get() {
if (myBar.get()==null) myBar.compareAndSet(null,init());
return myBar.get();
}
Bar init() { /* ... */ }
//...
}
EDITED: That will set once, with some lazy-initialization method. It's not perfect for blocking multiple calls to a (presumably expensive) init(), but it could be worse. You could stick the instantiation of myBar into constructor, and then later add a constructor that allows assignment as well, if provided the correct info.
There's some general discussion of thread-safe, singleton instantiation (which is pretty similar to your problem) at, for example, this site.
In theory it would be sufficient to rewrite startup() as follows:
public synchronized void startup() {
if (someObject == null) someObject = new SomeObject();
}
By the way, although the WoRmObject is final, threads can still invoke set() multiple times. You'll really need to add some synchronization.
update: I played a bit round it and created an SSCCE, you may find it useful to play a bit around with it :)
package com.stackoverflow.q2428725;
import java.util.concurrent.Callable;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
public class Test {
public static void main(String... args) throws Exception {
Bean bean = new Bean();
ScheduledExecutorService executor = Executors.newScheduledThreadPool(4);
executor.schedule(new StartupTask(bean), 2, TimeUnit.SECONDS);
executor.schedule(new StartupTask(bean), 2, TimeUnit.SECONDS);
Future<String> result1 = executor.submit(new GetTask(bean));
Future<String> result2 = executor.submit(new GetTask(bean));
System.out.println("Result1: " + result1.get());
System.out.println("Result2: " + result2.get());
executor.shutdown();
}
}
class Bean {
private String property;
private CountDownLatch latch = new CountDownLatch(1);
public synchronized void startup() {
if (property == null) {
System.out.println("Setting property.");
property = "foo";
latch.countDown();
} else {
System.out.println("Property already set!");
}
}
public String get() {
try {
latch.await();
} catch (InterruptedException e) {
// handle.
}
return property;
}
}
class StartupTask implements Runnable {
private Bean bean;
public StartupTask(Bean bean) {
this.bean = bean;
}
public void run() {
System.out.println("Starting up bean...");
bean.startup();
System.out.println("Bean started!");
}
}
class GetTask implements Callable<String> {
private Bean bean;
public GetTask(Bean bean) {
this.bean = bean;
}
public String call() {
System.out.println("Getting bean property...");
String property = bean.get();
System.out.println("Bean property got!");
return property;
}
}
The CountDownLatch will cause all await() calls to block until the countdown reaches zero.
It is most likely thread safe, from your description of the framework. There must have been a memory barrier somewhere between calling myobj.startup() and making myobj available to other threads. That guarantees that the writes in startup() will be visible to other threads. Therefore you don't have to worry about thread safety because the framework does it. There is no free lunch though; everytime another thread obtains access to myobj through the framework, it must involve sync or volatile read.
If you look into the framework and list the code in the path, you'll see sync/volatile in proper places that make your code thread safe. That is, if the framework is correctly implemented.
Let's examine a typical swing example, where a worker threads does some calculation, saves the results in a global variable x, then sends a repaint event. The GUI thread upon receiving the repaint event, reads the results from the global variable x, and repaints accordingly.
Neither the worker thread nor the repaint code does any synchronization or volatile read/write on anything. There must be tens of thousands of implementations like this. Luckily they are all thread safe even though the programmers paid no special attention. Why? Because the event queue is synchronized; we have a nice happends-before chain:
write x - insert event - read event - read x
Therefore write x and read x are properly synchronized, implicitly via event framework.
how about synchronization?
No it is not thread safe. Without synchronization, the new state of your variable might never get communicated to other threads.
Yes, as far as I know references are atomic so you will see either null or the reference. Note that the state of the referenced object is a completely different story
Could you use a ThreadLocal that only allows each thread's value to be set once?
There are a LOT of wrong ways to do lazy instantiation, especially in Java.
In short, the naive approach is to create a private object, a public synchronized init method, and a public unsynchronized get method that performs a null check on your object and calls init if necessary. The intricacies of the problem come in performing the null check in a thread safe way.
This article should be of use: http://en.wikipedia.org/wiki/Double-checked_locking
This specific topic, in Java, is discussed in depth in Doug Lea's 'Concurrent Programming in Java' which is somewhat out of date, and in 'Java Concurrency in Practice' coauthored by Lea and others. In particular, CPJ was published before the release of Java 5, which significantly improved Java's concurrency controls.
I can post more specifics when I get home and have access to said books.
This is my final answer, Regis1 :
/**
* Provides a simple write-one, read-many wrapper for an object reference for those situations
* where you have an instance variable which you would like to declare as final but can't because
* the instance initialization extends beyond construction.
* <p>
* An example would be <code>java.awt.Applet</code> with its constructor, <code>init()</code> and
* <code>start()</code> methods.
* <p>
* Threading Design : [ ] Single Threaded [x] Threadsafe [ ] Immutable [ ] Isolated
*
* #since Build 2010.0311.1923
*/
public class WormRef<T>
extends Object
{
private volatile T reference; // wrapped reference
public WormRef() {
super();
reference=null;
}
public WormRef<T> init(T val) {
// Use synchronization to prevent a race-condition whereby the following interation could happen between three threads
//
// Thread 1 Thread 2 Thread 3
// --------------- --------------- ---------------
// init-read null
// init-read null
// init-write A
// get A
// init-write B
// get B
//
// whereby Thread 3 sees A on the first get and B on subsequent gets.
synchronized(this) {
if(reference!=null) { throw new IllegalStateException("The WormRef container is already initialized"); }
reference=val;
}
return this;
}
public T get() {
if(reference==null) { throw new IllegalStateException("The WormRef container is not initialized"); }
return reference;
}
} // END PUBLIC CLASS
(1) Confer the game show "So you want to be a millionaire", hosted by Regis Philburn.
Just my little version based on AtomicReference. It's probably not the best, but I believe it to be clean and easy to use:
public static class ImmutableReference<V> {
private AtomicReference<V> ref = new AtomicReference<V>(null);
public boolean trySet(V v)
{
if(v == null)
throw new IllegalArgumentException("ImmutableReference cannot hold null values");
return ref.compareAndSet(null, v);
}
public void set(V v)
{
if(!trySet(v)) throw new IllegalStateException("Trying to modify an immutable reference");
}
public V get()
{
V v = ref.get();
if(v == null)
throw new IllegalStateException("Not initialized immutable reference.");
return v;
}
public V tryGet()
{
return ref.get();
}
}
First question: Why can't you just make start up a private method, called in the constructor, then it can be final. This would ensure thread safety after the constructor is called, as it is invisible before and only read after the constructor returns. Or re-factor your class structure so that the start-up method can create the MyClass object as part of its constructor. In may ways this particular case seems like a case of poor structure, where you really just want to make it final and immutable.
The easy Approach, if the class is immutable, and is read only after it is created, then wrap it in an Immutable List from guava. You can also make your own immutable wrapper which defensively copies when asked to return the reference, so this prevents a client from changing the reference. If it is immutable internally, then no further synchronization is needed, and unsynchronized reads are permissible. You can set your wrapper to defensively copy on request, so even attempts to write to it fail cleanly (they just don't do anything). You may need a memory barrier, or you may be able to do lazy initialisation, although note that lazy initialisation may require further synchronization, as you may get several unsynchronized read requests while the object is being constructed.
The slightly more involved approach would involve using an enumeration. Since enumerations are guaranteed singleton, then as soon as the enumeration is created it is fixed for ever. You still have to make sure that the object is internally immutable, but it does guarantee its singleton status. Without much effort.
The following class could answer your question. Some thread-safety achieved by using a volatile intermediate variable in conjunction with final value keeper in the provided generic. You may consider further increase of it by using synchronized setter/getter. Hope it helps.
https://stackoverflow.com/a/38290652/6519864

Categories

Resources