Overzealous null checking of backing field in my singleton? - vb.net

The code below represents a singleton that I use in my application. Lets assume that _MyObject = New Object represents a very expensive database call that I do not want to make more than once under any circumstance. To ensure that this doesn't happen, I first check if the _MyObject backing field is null. If it is, I break into a SyncLock to ensure that only one thread can get in here at a time. However, in the event that two threads get past the first null check before the singleton is instantiated, thread B would end up sitting at the SyncLock while thread A creates the instance. After thread A exits the lock, thread B would enter the lock and recreate the instance which would result in that expensive database call being made. To prevent this, I added an additional null check of the backing field which occurs within the lock. This way, if thread B manages to end up waiting at the lock, it will get through and do one more null check to ensure that it doesn't recreate the instance.
So is it really necessary to do two null checks? Would getting rid of the outer null check and just starting out with the Synclock be just the same? In other words, is thread-locking a variable just as fast as letting multiple threads access a backing field simultaneously? If so, the outer null check is superfluous.
Private Shared synclocker As New Object
Private Shared _MyObject As Object = Nothing
Public Shared ReadOnly Property MyObject As Object
Get
If _MyObject Is Nothing Then 'superfluous null check?
SyncLock synclocker
If _MyObject Is Nothing Then _MyObject = New Object
End SyncLock
End If
Return _MyObject
End Get
End Property

This will probably be better as an answer rather than a comment.
So, using Lazy to implement "do expensive operation only once, than return reference to the created instance":
Private Shared _MyObject As Lazy(Of Object) = New Lazy(Of Object)(AddressOf InitYourObject)
Private Shared Function InitYourObject() As Object
Return New Object()
End Function
Public Shared ReadOnly Property MyObject As Object
Get
Return _MyObject.Value
End Get
End Property
This is a very simple and thread-safe way of doing on-demand one time initialization. The InitYourObject method handles whatever initialization you need to do and returns an instance of the created class. On first request, the initialization method is called when you call _MyObject.Value, the subsequent requests will return the same instance.

You're absolutely right to have added the inner If statement (you would still have a race condition without it, as you correctly noted).
You are also correct that, from a purely-logical point of view, the outer check is superfluous. However, the outer null check avoids the relatively-expensive SyncLock operation.
Consider: if you've already created your singleton, and you happen to hit your property from 10 threads at once, the outer If is what prevents those 10 threads from queueing up to essentially do nothing. Synchronising threads isn't cheap, and so the added If is for performance rather than for functionality.

Related

Observable.Publish with rethrow behaviour

I have a cold Observable that might OnError when it is subscribed to. How can i create a cold Observable, that returns a single element (an object that receives as a dependency the source Observable), or propagates the OnError of the source.
Using the Publish operator, the onError handler it is not called.
Private Shared Sub Test()
Dim source = Observable.Throw(Of Integer)(New Exception)
' Dim source = Observable.Range(0, 9)
Dim obs = source.Publish(Function(published)
Return Observable.
Return(New ObjectThatConsumesXs(published))
End Function)
obs.Subscribe(Sub(a)
End Sub,
Sub(ex)
End Sub,
Sub()
End Sub)
End Sub
Private Class ObjectThatConsumesXs
Private _subscription As IDisposable
Public Sub New(source As IObservable(Of Integer))
_subscription = source.Subscribe(Sub(x)
End Sub,
Sub(ex)
End Sub,
Sub()
End Sub)
End Sub
End Class
EDIT:
This is going to be somehow a long description.
I have a device that is essentially a CAN Bus scanner. This device has a serial port, and upon receiving a Start command it starts mirroring whatever messages it captures on the CAN Bus until it receives a Stop command. The replied messages are wrapped in a variant of PPP Protocol to mitigate errors, given the fact that the serial port baud-rate is about 1MBaud.
I want to design a desktop application that connects to the scanner, sends commands to it, and receives the captured CAN messages. It should display the received messages in a ListBox/ListView, with the ability to live filter what is displayed by some criteria. It should also group by IDs embedded in each message, and display a list with encountered ID's and their total occurence. It should also display a total of distinct ID's, and a total count of messages.
What is received between a Start and a Stop command is a collection of messages that represent a record. The application should be capable to record multiple times in a session and must provide a way to persist records on disk along with applied filters, a user defined name, etc. The same application should be capable to import those records for offline analysis.
The fore mentioned ObjectThatConsumesXs is my record, that exposes it's contained messages as an Observable that reply to its subscribers(Reply operator).
I am using ReactiveUI - MVVM/WinForms/Reactive Extensions, and among others i have managed to design a service that exposes a GetRecordUntil function that returns an IObservable(Of Record). Upon subscription the observable emits a single Record that is updated with messages received from the scanner.
I am opened to suggestion regarding the design of the application. But i am afraid that my question should be at least re-tagged if not even renamed.
In general, I would suggest a design that doesn't have you passing IObservable(Of T) in as parameters.
The Observable interfaces provide a way for something you depend on (i.e. has no knowledge of you) to call you back.
However if you are passing an observable sequence to something, then you clearly know about it, and it clearly is expecting to be called (or react to ) stimulus. Why not just call methods on that dependency directly when the events happen?
Regardless, the current design you have will not pass on the OnError.
The outer sequence you guarantee to only ever OnNext a single ObjectThatConsumesXs and then complete the sequence.
Internally, that ObjectThatConsumesXs will subscribe to the published sequence, receive the error, but have no way to propagate that back to the other code path.
As another note, you have a type called ObjectThatConsumesXs, but you then go on to consumer the outer sequence directly within the other method.
Why the double handling?
If you can explain what it is that you are trying to do (not how you are trying to solve it), then I am sure the community can point you to a more appropriate design.

Synclock List or ListItem

MS reference: http://msdn.microsoft.com/en-us/library/3a86s51t(v=vs.71).aspx
"The type of the expression in a SyncLock statement must be a reference type, such as a class, a module, an interface, array or delegate."
Scenario: Multiple threads reading and editing a list.
I know this will avoid a race condition:
SyncLock TheList
TheList.item(0) = "string"
End SyncLock
But will this?
SyncLock TheList.item(0)
TheList.item(0) = "string"
End SyncLock
No, your second snippet is fundamentally wrong. Since you are replacing the object that you lock on. So another thread is going to take the lock on another object, you therefore have no thread-safety at all. A lock can only work if threads use the exact same object to store the lock state.
Notable too is the kind of object you take the lock on. Your second snippet does so on an interned string. Very, very bad since is very likely to cause deadlock. Any other code anywhere else might be wrong the same way and also take a lock on a string literal. If that happens to be "string" as well, you'll easily get completely undiagnosable deadlock.
Also the problem with your first snippet, other code might be taking a lock on the TheList object since it is probably public. Producing deadlock for the same reason. Boilerplate is that you always use a dedicated object to store the lock state that isn't used for anything else, only ever appearing in any code that accesses the list.
Private ListLock As Object = New Object

Is this simple VB.Net class thread safe? If not, how can I improve it?

Option Strict On
Public Class UtilityClass
Private Shared _MyVar As String
Public Shared ReadOnly Property MyVar() As String
Get
If String.IsNullOrEmpty(_MyVar) Then
_MyVar = System.Guid.NewGuid.ToString()
End If
Return _MyVar
End Get
End Property
Public Shared Sub SaveValue(ByVal newValue As String)
_MyVar = newValue
End Sub
End Class
While locking is a good general approach to adding thread safety, in many scenarios involving write-once quasi-immutability, where a field should become immutable as soon as a non-null value is written to it, Threading.Interlocked.CompareExchange may be better. Essentially, that method reads a field and--before anyone else can touch it--writes a new value if and only if the field matches the supplied "compare" value; it returns the value that was read in any case. If two threads simultaneously attempt a CompareExchange, with both threads specifying the field's present value as the "compare" value, one of the operations will update the value and the other will not, and each operation will "know" whether it succeeded.
There are two main usage patterns for CompareExchange. The first is most useful for generating mutable singleton objects, where it's important that everyone see the same instance.
If _thing is Nothing then
Dim NewThing as New Thingie() ' Or construct it somehow
Threading.Interlocked.CompareExchange(_thing, NewThing, Nothing)
End If
This pattern is probably what you're after. Note that if a thread enters the above code between the time another thread has done so and the time it has performed the CompareExchange, both threads may end up creating a new Thingie. If that occurs, whichever thread reaches the CompareExchange first will have its new instance stored in _thing, and the other thread will abandon its instance. In this scenario, the threads don't care whether they win or lose; _thing will have a new instance in it, and all threads will see the same instance there. Note also that because there's no memory barrier before the first read, it is theoretically possible that a thread which has examined the value of _thing sometime in the past might continue seeing it as Nothing until something causes it to update its cache, but if that happens the only consequence will be the creation of a useless new instance of Thingie which will then get discarded when the Interlocked.CompareExchange finds that _thing has already been written.
The other main usage pattern is useful for updating references to immutable objects, or--with slight adaptations--updating certain value types like Integer or Long.
Dim NewThing, WasThing As Thingie
Do
WasThing = _thing
NewThing = WasThing.WithSomeChange();
Loop While Threading.Interlocked.CompareExchange(_thing, NewThing, WasThing) IsNot WasThing
In this scenario, assuming there is some means by which, given a reference to Thingie, one may cheaply produce a new instance that differs in some desired way, it's possible to perform any such operation on _thing in a thread-safe manner. For example, given a String, one may easily produce a new String which has some characters appended. If one wished to append some text to a string in a thread-safe manner (such that if one thread attempts to add Fred and the other tries to add Joe, the net result would be to either append FredJoe or JoeFred, and not something like FrJoeed), the above code would have each thread read _thing, generate a version with its text appended and, try to update _thing. If some other thread updated _thing in the mean-time, abandon the last string that was constructed, make a new string based upon the updated _thing, and try again.
Note that while this approach isn't necessarily faster than the locking approach, it does offer an advantage: if a thread which acquires a lock gets stuck in an endless loop or otherwise waylaid, all threads will be forever blocked from accessing the locked resource. By contrast, if the WithSomeChanges() method above gets stuck in an endless loop, other users of _thing won't be affected.
With multithreaded code, the relevant question is: Can state be modified from several threads? If so, the code isn’t thread safe.
In your code, that’s the case: there are several places which mutate _MyVar and the code is therefore not thread safe. The best way to make code thread safe is almost always to make it immutable: immutable state is simply thread safe by default. Furthermore, code that doesn’t modify state across threads is simpler and usually more efficient than mutating multi-threaded code.
Unfortunately, it’s impossible to see without context whether (or how) your code could be made immutable from several threads. So we need to resort to locks which is slow, error-prone (see the other answer for how easy it is to get it wrong) and gives a false sense of security.
The following is my attempt to make the code correct with using locks. It should work (but keep in mind the false sense of security):
Public Class UtilityClass
Private Shared _MyVar As String
Private Shared ReadOnly _LockObj As New Object()
Public Shared ReadOnly Property MyVar() As String
Get
SyncLock _LockObj
If String.IsNullOrEmpty(_MyVar) Then
_MyVar = System.Guid.NewGuid.ToString()
End If
Return _MyVar
End SyncLock
End Get
End Property
Public Shared Sub SaveValue(ByVal newValue As String)
SyncLock _lockObj
_MyVar = newValue
End SyncLock
End Sub
End Class
A few comments:
We cannot lock on _MyVar since we change the reference of _MyVar, thus losing our lock. We need a separate dedicated locking object.
We need to lock each access to the variable, or at the very least every mutating access. Otherwise all the locking is for naught since it can be undone by changing the variable in another place.
Theoretically we do not need to lock if we only read the value – however, that would require double-checked locking which introduces the opportunity for more errors, so I’ve not done it here.
Although we don’t necessarily need to lock read accesses (see previous two points), we might still have to introduce a memory barrier somewhere to prevent reordering of read-write access to this property. I do not know when this becomes relevant because the rules are quite complex, and this is another reason I dislike locks.
All in all, it’s much easier to change the code design so that no more than one thread at a time has write access to any given variable, and to restrict all necessary communication between threads to well-defined communication channels via synchronised data structures.

Lazy<T>(bool) Constructor Documentation

I'm confusing myself reading Microsoft's documentation on the Lazy<T>(bool) constructor.
The parameter is described as:
isThreadSafe: true to make this instance usable concurrently by multiple threads; false to make the instance usable by only one thread at a time.
If the code I would normally write in an accessor is:
If _rulesCache Is Nothing Then
SyncLock (_lockRulesCache)
If _rulesCache Is Nothing Then
_rulesCache = New RulesCache()
End If
End SyncLock
End If
Return _rulesCache
Do I want to use True or False in the constructor of the Lazy type?
Private _rulesCache As New Lazy(Of RulesCache)(**?**)
So my accessor becomes:
Return _rulesCache.Value
1) Once the object is created, it can handle multiple thread access internally.
2) I just need to make sure that if there are multiple threads hitting the accessor close to simultaneously and the object doesn't exist, that it only gets created once.
According to the documentation, statement 1 implies that the parameter should be false. Statement 2 implies that the parameter should be true.
I feel like I'm over-thinking this and it's just making me more confused. Or are the two statements above actually at odds with each other, and I should just stick with the manual locking to manage the object instantiation?
Statement 2 is the desired interpretation. The parameter does not affect any behavior of the object after the lazy initialization is complete; it only prevents two threads from accidentally racing and instantiating it twice. You can verify that in Reflector if you're curious.

Another ConcurrentModificationException question

I've searched StackOverflow and there are many ConcurrentModificationException questions. After reading them, I'm still confused. I'm getting a lot of these exceptions. I'm using a "Registry" setup to keep track of Objects:
public class Registry {
public static ArrayList<Messages> messages = new ArrayList<Messages>();
public static ArrayList<Effect> effects = new ArrayList<Effect>();
public static ArrayList<Projectile> proj = new ArrayList<Projectile>();
/** Clears all arrays */
public static void recycle(){
messages.clear();
effects.clear();
proj.clear();
}
}
I'm adding and removing objects to these lists by accessing the ArrayLists like this: Registry.effects.add(obj) and Registry.effects.remove(obj)
I managed to get around some errors by using a retry loop:
//somewhere in my game..
boolean retry = true;
while (retry){
try {
removeEffectsWithSource("CHARGE");
retry = false;
}
catch (ConcurrentModificationException c){}
}
private void removeEffectsWithSource(String src) throws ConcurrentModificationException {
ListIterator<Effect> it = Registry.effects.listIterator();
while ( it.hasNext() ){
Effect f = it.next();
if ( f.Source.equals(src) ) {
f.unapplyEffects();
Registry.effects.remove(f);
}
}
}
But in other cases this is not practical. I keep getting ConcurrentModificationExceptions in my drawProjectiles() method, even though it doesn't modify anything. I suppose the culprit is if I touched the screen, which creates a new Projectile object and adds it to Registry.proj while the draw method is still iterating.
I can't very well do a retry loop with the draw method, or it will re-draw some of the objects. So now I'm forced to find a new solution.. Is there a more stable way of accomplishing what I'm doing?
Oh and part 2 of my question: Many people suggest using ListIterators (as I have been using), but I don't understand.. if I call ListIterator.remove() does it remove that object from the ArrayList it's iterating through, or just remove it from the Iterator itself?
Top line, three recommendations:
Don't do the "wrap an exception in a loop" thing. Exceptions are for exceptional conditions, not control flow. (Effective Java #57 or Exceptions and Control Flow or Example of "using exceptions for control flow")
If you're going to use a Registry object, expose thread-safe behavioral, not accessor methods on that object and contain the concurrency reasoning within that single class. Your life will get better. No exposing collections in public fields. (ew, and why are those fields static?)
To solve the actual concurrency issues, do one of the following:
Use synchronized collections (potential performance hit)
Use concurrent collections (sometimes complicated logic, but probably efficient)
Use snapshots (probably with synchronized or a ReadWriteLock under the covers)
Part 1 of your question
You should use a concurrent data structure for the multi-threaded scenario, or use a synchronizer and make a defensive copy. Probably directly exposing the collections as public fields is wrong: your registry should expose thread-safe behavioral accessors to those collections. For instance, maybe you want a Registry.safeRemoveEffectBySource(String src) method. Keep the threading specifics internal to the registry, which seems to be the "owner" of this aggregate information in your design.
Since you probably don't really need List semantics, I suggest replacing these with ConcurrentHashMaps wrapped into Set using Collections.newSetFromMap().
Your draw() method could either a) use a Registry.getEffectsSnapshot() method that returns a snapshot of the set; or b) use an Iterable<Effect> Registry.getEffects() method that returns a safe iterable version (maybe just backed by the ConcurrentHashMap, which won't throw CME under any circumstances). I think (b) is preferable here, as long as the draw loop doesn't need to modify the collection. This provides a very weak synchronization guarantee between the mutator thread(s) and the draw() thread, but assuming the draw() thread runs often enough, missing an update or something probably isn't a big deal.
Part 2 of your question
As another answer notes, in the single-thread case, you should just make sure you use the Iterator.remove() to remove the item, but again, you should wrap this logic inside the Registry class if at all possible. In some cases, you'll need to lock a collection, iterate over it collecting some aggregate information, and make structural modifications after the iteration completes. You ask if the remove() method just removes it from the Iterator or from the backing collection... see the API contract for Iterator.remove() which tells you it removes the object from the underlying collection. Also see this SO question.
You cannot directly remove an item from a collection while you are still iterating over it, otherwise you will get a ConcurrentModificationException.
The solution is, as you hint, to call the remove method on the Iterator instead. This will remove it from the underlying collection as well, but it will do it in such a way that the Iterator knows what's going on and so doesn't throw an exception when it finds the collection has been modified.