public class MyTask : IDisposable { ... }
MyTask task = new MyTask(() => SomeTask);
task.Completed += (s, e) =>
{
// do something with result
...
// dispose of this instance
((MyTask)s).Dispose();
};
// execute the task
task.Execute();
Clearly I cannot tell when the task will be completed, so the only actual place, as I see it, that i can dispose of this instance is in Completed event.
Is this safe to do?
There is, alas, no general rule as to when it is safe to call Dispose. If Microsoft had specified that Dispose must be safe to call at any time when an object isn't in use, complying with such a rule would seldom have been difficult; in cases where a class might not always be able to perform all necessary cleanup immediately(*), it would generally be possible for it to set a flag and/or otherwise arrange to have necessary cleanup performed at the next opportunity. Unfortunately, Microsoft does not specify that Dispose implementations have to handle asynchronous Dispose requests, nor is there any general way for an object which holds the last useful reference to an IDisposable instance to ask for notification when it would be safe to dispose.
Despite the general lack of assurance as to when it is safe to call Dispose, many particular classes which implement Dispose do offer guarantees as to when it may safely be called. If one knows that a particular object is of a type which can be safely disposed in a particular context, one may dispose it then. Especially in cases where an event from an object may be the only opportunity to Dispose it in a threading context it could know about, and where disposing an object within an event handler would make sense, it should be safe to dispose of the object. Any properly-written event handlers should be prepared for the possibility that the object sending the event may be disposed between the time the system decides that they should run, and the time it actually runs them.
(*) The essential purpose of IDisposable is to allow an object to notify entities which are outside it but are acting on its behalf to the detriment of other entities, that they should no longer do so [e.g. to tell a file system that it should no longer grant an object exclusive access to a file]. Such action is referred to as "releasing resources". The fact that someone holds the last surviving reference to an object may imply that no other thread can be using that object, but does not imply that no other thread is using any non-thread-safe entities whose resources need to be released.
Related
Shouldn't finalize() execute immediately when gc() is called? The order of output result is a little unconvincing.
class Test
{
int x = 100;
int y = 115;
protected void finalize()
{System.out.println("Resource Deallocation is completed");}
}
class DelObj
{
public static void main(String arg[])
{
Test t1 = new Test();
System.out.println("Values are "+t1.x+", "+t1.y+"\nObject refered by t1 is at location: "+t1);
t1 = null; // dereferencing
System.gc(); // explicitly calling
Test t2= new Test();
System.out.println("Values are "+t2.x+", "+t2.y+"\nObject refered by t2 is at location: "+t2);
}
}
Got the execution result of finalize() after a new object is created, referred by t2:
D:\JavaEx>java DelObj
Values are 100, 115
Object refered by t1 is at location: Test#6bbc4459
Values are 100, 115
Object refered by t2 is at location: Test#2a9931f5
Resource Deallocation is completed
Calling System.gc() only provides a hint to the JVM, but does not guaranty that an actual garbage collection will happen.
However, the bigger problem with your expectation is that garbage collection is not the same as finalization.
Referring to the Java 6 documentation, System.gc() states:
Runs the garbage collector.
Calling the gc method suggests that the Java Virtual Machine expend effort toward recycling unused objects in order to make the memory they currently occupy available for quick reuse. …
Compare to System.runFinalization():
Runs the finalization methods of any objects pending finalization.
Calling this method suggests that the Java Virtual Machine expend effort toward running the finalize methods of objects that have been found to be discarded but whose finalize methods have not yet been run. …
So there can be “pending finalization”, resp. “objects that have been found to be discarded but whose finalize methods have not yet been run”.
Unfortunately, Java 6’s documentation of finalize() starts with the misleading sentence:
Called by the garbage collector on an object when garbage collection determines that there are no more references to the object.
whereas garbage collection and finalization are two different things, hence, the finalize() method is not called by the garbage collector. But note that the subsequent documentation says:
The Java programming language does not guarantee which thread will invoke the finalize method for any given object.
So when you say “The order of output result is a little unconvincing”, recall that we’re talking about multi-threading here, so in absence of additional synchronization, the order is outside your control.
The Java Language Specification even says:
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.
and later on
The Java programming language imposes no ordering on finalize method calls. Finalizers may be called in any order, or even concurrently.
In practice, the garbage collector will only enqueue objects needing finalization, while one or more finalizer threads poll the queue and execute the finalize() methods. When all finalizer threads are busy executing particular finalize() methods, the queue of objects needing finalization may grow arbitrary long.
Note that modern JVMs contain an optimization for those classes not having a dedicated finalize() method, i.e. inherit the method from Object or just have an empty method. Instances of these classes, the majority of all objects, skip this finalization step and their space gets reclaimed immediately.
So if you added a finalize() method just to find out when the object gets garbage collected, it’s the very presence of that finalize() method which slows down the process of the memory reclamation.
So better refer to the JDK 11 version of finalize():
Deprecated.
The finalization mechanism is inherently problematic. Finalization can lead to performance issues, deadlocks, and hangs. Errors in finalizers can lead to resource leaks; there is no way to cancel finalization if it is no longer necessary; and no ordering is specified among calls to finalize methods of different objects. Furthermore, there are no guarantees regarding the timing of finalization. The finalize method might be called on a finalizable object only after an indefinite delay, if at all. Classes whose instances hold non-heap resources should provide a method to enable explicit release of those resources, and they should also implement AutoCloseable if appropriate. The Cleaner and PhantomReference provide more flexible and efficient ways to release resources when an object becomes unreachable.
So when your object does not contain a non-memory resource, hence, doesn’t actually need finalization, you can use
class Test
{
int x = 100;
int y = 115;
}
class DelObj
{
public static void main(String[] arg)
{
Test t1 = new Test();
System.out.println("Values are "+t1.x+", "+t1.y+"\nObject refered by t1 is at location: "+t1);
WeakReference<Test> ref = new WeakReference<Test>(t1);
t1 = null; // dereferencing
System.gc(); // explicitly calling
if(ref.get() == null) System.out.println("Object deallocation is completed");
else System.out.println("Not collected");
Test t2= new Test();
System.out.println("Values are "+t2.x+", "+t2.y+"\nObject refered by t2 is at location: "+t2);
}
}
The System.gc() call still is only a hint, but you will find your object being collected afterwards in most practical cases. Note that the hash code printed for the objects, like with Test#67f1fba0 has nothing to do with memory locations; that’s a tenacious myth. The patterns behind object memory addresses is often unsuitable for hashing, further most modern JVMs can move objects to different memory locations during their lifetime, whereas the identity hash code is guaranteed to stay the same.
Java docs state following regarding synchronization of constructor:
Note that constructors cannot be synchronized — using the synchronized keyword with a constructor is a syntax error. Synchronizing constructors doesn't make sense, because only the thread that creates an object should have access to it while it is being constructed.
Warning: When constructing an object that will be shared between
threads, be very careful that a reference to the object does not
"leak" prematurely. For example, suppose you want to maintain a List
called instances containing every instance of class. You might be
tempted to add the following line to your constructor:
instances.add(this); But then other threads can use instances to
access the object before construction of the object is complete.
I am not able to understand this whole block. First it states that only the thread that creates an object has access to constructor. Then it warns of premature leak which may cause issues if other threads access the object before construction is complete. Are not these two things in contradiction. If only the creating thread can access the constructor then how can other threads prematurely access the object as it can only be accessed once contructor has run fully?
Any input would be of great help.
Imagine two threads that both have access to a global List (called "instances") holding instances of the class in question. Thread 1 continuously cycles through the list and does something with each instance. Thread 2 goes its own merry way, and occasionally constructs a new instance of the class. If the class would add itself to the List in its constructor (using instances.add(this)) Thread 1 would immediately get access to the instance and could do things with it before it is fully constructed, resulting in unpredictable behavior.
There may be a misunderstanding of the word "should". You wrote: "First it states that only the thread that creates an object has access to constructor. " However, the Java docs say: "only the thread that creates an object should have access to it while it is being constructed", which means that you should take care that only one thread has access to the object while it is being constructed.
I always had this specific scenario worry me for eons. Let's say my class looks like this
public class Person {
public Address Address{get;set;}
public string someMethod()
{}
}
My question is, I was told by my fellow developers that the Address propery of type Address, is not thread safe.
From a web request perspective, every request is run on a separate thread and every time
the thread processes the following line in my business object or code behind, example
var p = new Person();
it creates a new instance of Person object on heap and so the instance is accessed by the requesting thread, unless and otherwise I spawn multiple threads in my application.
If I am wrong, please explain to me why I am wrong and why the public property (Address) is not thread safe?
Any help will be much appreciated.
Thanks.
If the reference to your Person instance is shared among multiple threads then multiple threads could potentially change Address causing a race condition. However unless you are holding that reference in a static field or in Session (some sort of globally accessible place) then you don't have anything to be worried about.
If you are creating references to objects in your code like you have show above (var p = new Person();) then you are perfectly thread safe as other threads will not be able to access the reference to these objects without resorting to nasty and malicious tricks.
Your property is not thread safe, because you have no locking to prevent multiple writes to the property stepping on each others toes.
However, in your scenario where you are not sharing an instance of your class between multiple threads, the property doesn't need to be thread safe.
Objects that are shared between multiple threads, where each thread can change the state of the object, then all state changes need to be protected so that only one thread at a time can modify the object.
You should be fine with this, however there are a few things I'd worry about...
If your Person object was to be modified or held some disposable resources, you could potentially find that one of the threads will be unable to read this variable. To prevent this, you will need to lock the object before read/writing it to ensure it won't be trampled on by other threads. The easiest way is by using the lock{} construct.
Is there any way to determine if an object is locked in C#? I have the unenviable position, through design where I'm reading from a queue inside a class, and I need to dump the contents into a collection in the class. But that collection is also read/write from an interface outside the class. So obviously there may be a case when the collection is being written to, as the same time I want to write to it.
I could program round it, say using delegate but it would be ugly.
You can always call the static TryEnter method on the Monitor class using a value of 0 for the value to wait. If it is locked, then the call will return false.
However, the problem here is that you need to make sure that the list that you are trying to synchronize access to is being locked on itself in order to synchronize access.
It's generally bad practice to use the object that access is being synchronized as the object to lock on (exposing too much of the internal details of an object).
Remember, the lock could be on anything else, so just calling this on that list is pointless unless you are sure that list is what is being locked on.
Monitor.TryEnter will succeed if the object isn't locked, and will return false if at this very moment, the object is locked. However, note that there's an implicit race here: the instance this method returns, the object may not be locked any more.
I'm not sure if a static call to TryEnter with a time of 0 will guarantee that the lock will not be acquired if it is available. The solution I did to test in debug mode that the sync variable was locked was using the following:
#if DEBUG
// Make sure we're inside a lock of the SyncRoot by trying to lock it.
// If we're able to lock it, that means that it wasn't locked in the first
// place. Afterwards, we release the lock if we had obtained it.
bool acquired = false;
try
{
acquired = Monitor.TryEnter(SyncRoot);
}
finally
{
if (acquired)
{
Monitor.Exit(SyncRoot);
}
}
Debug.Assert(acquired == false, "The SyncRoot is not locked.");
#endif
Monitor.IsEntered
Determines whether the current thread holds the lock on the specified object.
Available since 4.5
Currently you may call Monitor.TryEnter to inspect whether object is locked or not.
In .NET 4.0 CLR team is going to add "Lock inspection API"
Here is a quotation from Rick Byers article:
lock inspection
We're adding some simple APIs to ICorDebug which allow you to explore managed locks (Monitors). For example, if a thread is blocked waiting for a lock, you can find what other thread is currently holding the lock (and if there is a time-out).
So, with this API you will be able to check:
1) What object is holding a lock?
2) Who’s waiting for it?
Hope this helps.
In a digital signal acquisition system, often data is pushed into an observer in the system by one thread.
example from Wikipedia/Observer_pattern:
foreach (IObserver observer in observers)
observer.Update(message);
When e.g. a user action from e.g. a GUI-thread requires the data to stop flowing, you want to break the subject-observer connection, and even dispose of the observer alltogether.
One may argue: you should just stop the data source, and wait for a sentinel value to dispose of the connection. But that would incur more latency in the system.
Of course, if the data pumping thread has just asked for the address of the observer, it might find it's sending a message to a destroyed object.
Has someone created an 'official' Design Pattern countering this situation? Shouldn't they?
If you want to have the data source to always be on the safe side of concurrency, you should have at least one pointer that is always safe for him to use.
So the Observer object should have a lifetime that isn't ended before that of the data source.
This can be done by only adding Observers, but never removing them.
You could have each observer not do the core implementation itself, but have it delegate this task to an ObserverImpl object.
You lock access to this impl object. This is no big deal, it just means the GUI unsubscriber would be blocked for a little while in case the observer is busy using the ObserverImpl object. If GUI responsiveness would be an issue, you can use some kind of concurrent job-queue mechanism with an unsubscription job pushed onto it. ( like PostMessage in Windows )
When unsubscribing, you just substitute the core implementation for a dummy implementation. Again this operation should grab the lock. This would indeed introduce some waiting for the data source, but since it's just a [ lock - pointer swap - unlock ] you could say that this is fast enough for real-time applications.
If you want to avoid stacking Observer objects that just contain a dummy, you have to do some kind of bookkeeping, but this could boil down to something trivial like an object holding a pointer to the Observer object he needs from the list.
Optimization :
If you also keep the implementations ( the real one + the dummy ) alive as long as the Observer itself, you can do this without an actual lock, and use something like InterlockedExchangePointer to swap the pointers.
Worst case scenario : delegating call is going on while pointer is swapped --> no big deal all objects stay alive and delegating can continue. Next delegating call will be to new implementation object. ( Barring any new swaps of course )
You could send a message to all observers informing them the data source is terminating and let the observers remove themselves from the list.
In response to the comment, the implementation of the subject-observer pattern should allow for dynamic addition / removal of observers. In C#, the event system is a subject/observer pattern where observers are added using event += observer and removed using event -= observer.