lundi 6 mars 2017

Is The Following VB.NET Implementation Of Random Thread-Safe?

I know there are many thread-safety questions especially regarding the Random class in VB.NET and C#. I've read through several as well as a blog post from Jon Skeet (http://ift.tt/2md2RX5); yet I'm still having a difficult time assessing the thread safety of my piece of code. I apologize a priori for adding yet another question of this form.

My code is based off of the aforementioned blog post, but I attempted to implement the comments from Andrew Shapira near the bottom of the post.

Background: Any code that calls this class (directly or indirectly) is typically ran on multiple threads without the use of any type of thread-locking. While I understand I can pass the onus of thread safety to any calling code, I would prefer to make this class handle multiple threads on its own.

Option Explicit On
Option Strict On
Imports System.Threading

Public NotInheritable Class ThreadSafeRandom

    Private Shared globalSeed As Integer = 0

    Private Shared Function CreateRandom(ByVal initialSeed As Integer) As Random

        Dim newRandom As Random

        If initialSeed <> 0 Then
            newRandom = New Random(initialSeed)
            Return newRandom
        End If

        Dim seed As Integer = CInt(Now.Ticks And &HFFFF)

        Interlocked.CompareExchange(globalSeed, seed, 0)

        newRandom = New Random(globalSeed)

        Interlocked.Increment(globalSeed)

        Return newRandom
    End Function

    Public Shared Function RandomInteger(ByVal lowerBound As Integer,
                                         ByVal exclusiveUpperBound As Integer,
                                         Optional ByVal seed As Integer = 0) As Integer

        Dim newRandom As Random = CreateRandom(seed)
        Return newRandom.Next(lowerBound, exclusiveUpperBound)
    End Function
End Class

Explanation: globalSeed is the value that gets passed into the Random constructor by default. Every time it gets passed, it gets incremented via System.Threading.Interlocked in the CreateRandom function.

CreateRandom is the Private function that is called within the Public function RandomInteger. The dual purpose of CreateRandom is to assure that the same seed value is never passed while at the same time allows for a new Random object to always be created thus avoiding potential thread issues.

Lastly, in order to allow a user to replicate results, the class allows for user-inputted seed values.

Question(s): Is ThreadSafeRandom truly thread safe? If not, is it possible to implement it in thread-safe way without completely changing the implementation?




Aucun commentaire:

Enregistrer un commentaire