In C++, the lifetime of an object begins when the constructor finishes successfully. Inside the constructor, the object does not exist yet.
Q: What does emitting an exception from a constructor mean?
A: It means that construction has failed, the object never existed, its lifetime never began. [source]
My question is: Does the same hold true for Java? What happens, for example, if I hand this to another object, and then my constructor fails?
Foo()
{
Bar.remember(this);
throw new IllegalStateException();
}
Is this well-defined? Does Bar now have a reference to a non-object?
The object exists, but it's not been initialized properly.
This can happen whenever this leaks during construction (not just when you throw an exception).
It's a very problematic situation, because some commonly assumed guarantees don't hold true in this situation (for example final fields could seem to change their value during construction).
Therefore you should definitely avoid leaking this in the constructor.
This IBM developerWorks article describes the precautions to take when constructing objects and the reasoning behind those precautions. While the article discusses the subject in the light of multi-threading, you can have similar problems in a single-threaded environment when unknown/untrusted code gets a reference to this during construction.
You should never open resources like a file writer in your constructor. Create a init method instead and do it from there. Then you're safe.
This code is not exception safe and neither would be exception safe in C++. It's same bug regardless of the language you use.
Related
We are using the Java Wrapper implementation of Compact Language Detector 2.
Is the detect() function thread-safe?
From what I understand, it invokes this library function.
No, it is not thread safe if the native code was compiled with CLD2_DYNAMIC_MODE set, which you could test using the function isDataDynamic().
The native function manipulates the static class variable kScoringtables. If CLD2_DYNAMIC_MODE is defined at compilation, this variable is initialized to a set of null tables (NULL_TABLES) and can later be loaded with dynamic data, or unloaded, potentially by other threads.
It would be possible for the kScoringtables.quadgram_obj to be non-null at the line 1762 null check and then the kScoringtables address altered before it is added to the cross-thread ScoringContext object on line 1777. In this case, the wrong pointer would be passed to ApplyHints on line 1785, potentially causing bad things to happen at line 1606.
This would be a very rare race condition, but possible nonetheless, and is not thread safe for the same reason the standard "lazy getter" is not thread safe.
To make this thread-safe, you would have to either test that isDataDynamic() returns false, or ensure the loadDataFromFile, loadDataFromRawAddress, and unloadData functions could not be called by a different thread while you are executing this method (or at least until you are past line 1777...)
I am not using the finalize method in my application but this question is out of curiosity.
Assume that there is finalize method in a class and I would like to log a warning message that finalize was not called.
How to do this ?
Any tips ?
Two possibilities--In either case, you need a singleton collection.
1) When each object is constructed add a unique key (String) that identifies the object--(but not the object itself!) to the collection. When the finalizer is called, remove it's key from the collection.
At any given time, outstanding instances are available in the collection.
2) Okay, you CAN add the object itself to the collection if you really want to, but the collection must be a collection of the proper reference class. This is harder and requires a little research--look into reference classes (WeakReference/PhantomReference/??). I haven't looked at them for a few years and forget exactly which one does what, but this is exactly the kind of work the Reference classes were made for.
Be careful with 2, I think there is a chance that iterating through the reference collection could resurrect a dead class or stop one from being collected.
The reason for both caveats is that if you store a reference in a normal collection it will never be eligible for collection so no finalizer will ever be called.
The JVM guarantees that the method will be called before the object is disposed, as per JLS 12.6. Finalization of Class Instances:
The Java programming language does not specify how soon a finalizer will be invoked, except to say that it will happen before the storage for the object is reused.
You are trying to prove that JVM does not follow the JLS, which would be a bug.
Looking at Azul Zulu OpenJDK 11 source we can observe that finaliztions are run with java.lang.ref.Finalizer object which in turn uses jdk.internal.misc.JavaLangAccess.invokeFinalize(Object) method to call Object.finalize().
JavaLangAccess instance is obtained from jdk.internal.misc.SharedSecrets which allows to setup a custom instance of JavaLangAccess. Perhaps you could create your own JavaLangAccess instance with additional logging in invokeFinalize() method?
I have a data structure that I occasionally wish to modify, and occasionally wish to replace outright. At the moment, I'm storing this in an AtomicReference, and using synchrnonized blocks (synchronized on the AtomicReference itself, not its stored value) when I need to modify it, rather than replace it.
So something like:
public void foo(AtomicReference reference){
synchronized(reference){
reference.get()
.performSomeModification();
}
}
Notice that the modifying call is a member of the wrapped value, not the atomic reference, and is not guaranteed to have any thread safety of its own.
Is this safe? Findbugs (a freeware code reviewing tool) had this to say about it, so now I'm worried there's something happening under the hood, where it may be prematurely releasing the lock or something. I've also seen documentation referencing AtomicReference as specifically for immutable things.
Is this safe? If it isn't I could create my own Reference-storing class that I would be more certain about the behavior of, but I don't want to jump to conclusions.
From the linked documentation:
For example, synchronizing on an AtomicBoolean will not prevent other threads from modifying the AtomicBoolean.
It can't prevent other threads from modifying the AtomicBoolean because it can't force other threads to synchronize on the AtomicBoolean.
If I understand your question correctly, your intention is to synchronize calls to performSomeModification(). The code you've written will achieve that, if and only if every call to performSomeModification() is synchronized on the same object. As in the example from the docs, the basic problem is the enforceability of that requirement. You can't force other callers to synchronize on the AtomicReference. You or some other developer who comes after you could easily call performSomeModification() without external synchronization.
You should make it hard to use your API incorrectly. Since AtomicReference is a generic type (AtomicReference<V>), you can enforce the synchronization in a variety of ways, depending on what V is:
If V is an interface, you could easily wrap the instance in a synchronized wrapper.
If V is a class that you can modify, you could synchronize performSomeModification(), or create a subclass in which it is synchronized. (Possibly an anonymous subclass produced by a factory method.)
If V is a class that you cannot modify, it may be difficult to wrap. In that case, you could encapsulate the AtomicReference in a class that you do control, and have that class perform the required synchronization.
Are Mutable Atomic References a Bad Idea?
Definitely not! AtomicReference is designed to provide thread-safe, atomic updates of the underlying reference. In fact, the Javadoc description of AtomicReference is:
An object reference that may be updated atomically.
So they most definitely are designed to be mutated!
Is this safe?
It depends on what you mean by "safe", and what the rest of your code is doing. There's nothing inherently unsafe about your snippet of code in isolation. It's perfectly valid, though perhaps a bit unusual, to synchronize on an AtomicReference. As a developer unfamiliar with this code, I would see the synchronization on reference and assume that it means that the underlying object may be replaced at any time, and you want to make sure your code is always operating on the "newest" reference.
The standard best practices for synchronization apply, and violating them could result in unsafe behavior. For example, since you say performSomeModification() is not thread-safe, it would be unsafe if you accessed the underlying object somewhere else without synchronizing on reference.
public void bar(AtomicReference reference) {
// no synchronization: performSomeModification could be called on the object
// at the same time another thread is executing foo()
reference.get().performSomeModification();
}
If could also be "unsafe" if your application requires that only one instance of the underlying object be operated on at any one time, and you haven't synchronized on the reference when .set()ing it:
public void makeNewFoo(AtomicReference reference) {
// no synchronication on "reference", so it may be updated by another thread
// while foo() is executing performSomeModification() on the "old" reference
SomeObject foo = new SomeObject();
reference.set(foo);
}
If you need to synchronize on the AtomicReference, do so, it's perfectly safe. But I would highly recommend adding a few code comments about why you're doing it.
JMM (Java Memory Model) is free to reorder statements.
Of course, this is especially tricky when dealing with multithreading environment.
JMM rules precised that volatile and final variables are always fully initialized before constructor finishes and if and only if reference hasn't "escape" from within constructor.
It implies that "normal" variables (non-final and non-volatile) aren't expected to be seen up-to-date by any concurrent threads.
My question might seem stupid at first glance, but it really doesn't:
Are any object's references set AFTER constructor completes (completes not meaning with initialization of all variables already made, but simply reaching the end of the 'constructor' process)? Is there a rule in any JSR asserting it?
Or might it exist an exceptional case where any reference could be sent back to client BEFORE constructor completes?
Indeed, if statements reordering is reputed so free, it may also imply the sending of the object's reference 'happens-before' constructor completes. So, we'd come across the same case of the "this escape" to avoid.
To put it in a nutshell, is reference ALWAYS be sent after constructor completes?
After searching into the JLS: the only place where returning of object's reference is related is: (excerpt of JSR-12.5)
Just before a reference to the newly created object is returned as the
result, the indicated constructor is processed to initialize the new
object using the following procedure:
No relation to JMM ... therefore it can be ensured that constructor completion always happens-before passing reference whatever the case.
Within the context of a thread the reference will be set. However, the JMM allows shared variables to be set in one thread and not yet synchronised to the other thread.
Volatile and final guarantee this by guaranteeing inter-thread synchronisation of reads and writes to the variable.
In what situations in java is explicit nulling useful. Does it in any way assist the garbage collector by making objects unreachable or something? Is it considered to be a good practice?
In Java it can help if you've got a very long-running method, and the only reference to the an object is via a local variable. Setting that local variable to null when you don't need it any more (but when the method is going to continue to run for a long time) can help the GC. (In C# this is very rarely useful as the GC takes "last possible use" into account. That optimization may make it to Java some time - I don't know.)
Likewise if you've got a member field referring to an object and you no longer need it, you could potentially aid GC by setting the field to null.
In my experience, however, it's rarely actually useful to do either of these things, and it makes the code messier. Very few methods really run for a long time, and setting a variable to null really has nothing to do with what you want the method to achieve. It's not good practice to do it when you don't need to, and if you do need to you should see whether refactoring could improve your design in the first place. (It's possible that your method or type is doing too much.)
Note that setting the variable to null is entirely passive - it doesn't inform the garbage collector that the object can be collected, it just avoids the garbage collector seeing that reference as a reason to keep the object alive next time it (the GC) runs.
In general it isn't needed (of course that can depend on the VM implementation). However if you have something like this:
private static final Map<String, String> foo;
and then have items in the map that you no longer need they will not be eligible for garbage collection so you would need to explicitly remove them. There are many cases like this (event listeners is another area that this can happen with).
But doing something like this:
void foo()
{
Object o;
// use o
o = null; // don't bother doing this, it isn't going to help
}
Edit (forgot to mention this):
If you work at it, you should find that 90-95% of the variables you declare can be made final. A final variable cannot change what it points at (or what its value is for primitives). In most cases where a variable is final it would be a mistake (bug) for it to receive a different value while the method is executing.
If you want to be able to set the variable to null after use it cannot be final, which means that you have a greater chance to create bugs in the code.
One special case I found it useful is when you have a very large object, and want to replace it with another large object. For example, look at the following code:
BigObject bigObject = new BigObject();
// ...
bigObject = new BigObject(); // line 3
If an instance of BigObject is so large that you can have only one such instance in the heap, line 3 will fail with OutOfMemoryError, because the 1st instance cannot be freed until the assignment instruction in line 3 completes, which is obviously after the 2nd instance is ready.
Now, if you set bigObject to null right before line 3:
bigObject = null;
bigObject = new BigObject(); // line 3
the 1st instance can be freed when JVM runs out of heap during the construction of the 2nd instance.
From "Effective Java" : use it to eliminate obsolete object references. Otherwise it can lead to memory leaks which can be very hard to debug.
public Object pop(){
if(size == 0)
throw new EmptyStatckException();
Object result = elements[--size];
elements[size] = null; //Eliminate Object reference
return result;
}
If you are nulling an object that is about to go out of scope anyway when your method block closes, then there is no benefit whatsoever in terms of garbage collection. It is not unusual to encounter people who don't understand this who work really hard to set a lot of things to null needlessly.
Explicit nulling can help with GC in some rare situations where all of the following are true:
The variable is the only (non-weak) reference to the object
You can guarantee that the object will no longer be needed
The variable will stay in scope for an extended period of time (e.g. it is a field in a long-lived object instance)
The compiler is unable to prove that the object is no longer used, but you are able to guarantee this though your superior logical analysis of the code :-)
In practice this is quite rare in good code: if the object is no longer needed, you should normally be declaring it in a narrower scope anyway. For example, if you only need the object during a single invocation of a method, it should be a local variable, not a field in the enclosing object.
One situation where explicit nulling is genuinely useful: if null is used to indicate a specific state then setting to a null value is sometimes going to be necessary and useful. Null is a useful value in itself for a couple of reasons:
Null checks are extremely fast, so conditional code that checks for null is typically more efficient than many alternatives (e.g. calling object.equals())
You get an immediate NullPointerException if you try to dereference it. This is useful because it is good Fail Fast coding style that will help you to catch logic errors.
See also WeakReference in J2SE.