Lazy<T> Klasse

Definition

Bietet Unterstützung für die faule Initialisierung.

generic <typename T>
public ref class Lazy
public class Lazy<T>
[System.Runtime.InteropServices.ComVisible(false)]
[System.Serializable]
public class Lazy<T>
type Lazy<'T> = class
[<System.Runtime.InteropServices.ComVisible(false)>]
[<System.Serializable>]
type Lazy<'T> = class
Public Class Lazy(Of T)

Typparameter

T

Der Typ des Objekts, das lazily initialisiert wird.

Vererbung
Lazy<T>
Abgeleitet
Attribute

Beispiele

Im folgenden Beispiel wird die Verwendung der Lazy<T>-Klasse veranschaulicht, um eine faule Initialisierung mit Zugriff von mehreren Threads bereitzustellen.

Anmerkung

Im Beispiel wird der Lazy<T>(Func<T>)-Konstruktor verwendet. Außerdem wird die Verwendung des Lazy<T>(Func<T>, Boolean)-Konstruktors (angeben true für isThreadSafe) und des Lazy<T>(Func<T>, LazyThreadSafetyMode)-Konstruktors (angeben LazyThreadSafetyMode.ExecutionAndPublication für mode) veranschaulicht. Wenn Sie zu einem anderen Konstruktor wechseln möchten, ändern Sie einfach, welche Konstruktoren auskommentiert sind.

Ein Beispiel, das das Zwischenspeichern von Ausnahmen mit denselben Konstruktoren veranschaulicht, finden Sie im Lazy<T>(Func<T>)-Konstruktor.

Im Beispiel wird eine LargeObject Klasse definiert, die durch einen von mehreren Threads lazily initialisiert wird. Die vier wichtigen Codeabschnitte veranschaulichen die Erstellung des Initialisierers, der Factorymethode, der tatsächlichen Initialisierung und des Konstruktors der LargeObject-Klasse, die beim Erstellen des Objekts eine Meldung anzeigt. Am Anfang der Main-Methode erstellt das Beispiel den threadsicheren Lazy Initializer für LargeObject:

lazyLargeObject = new Lazy<LargeObject>(InitLargeObject);

// The following lines show how to use other constructors to achieve exactly the
// same result as the previous line:
//lazyLargeObject = new Lazy<LargeObject>(InitLargeObject, true);
//lazyLargeObject = new Lazy<LargeObject>(InitLargeObject,
//                               LazyThreadSafetyMode.ExecutionAndPublication);
let lazyLargeObject = Lazy<LargeObject> initLargeObject

// The following lines show how to use other constructors to achieve exactly the
// same result as the previous line:
//     let lazyLargeObject = Lazy<LargeObject>(initLargeObject, true)
//     let lazyLargeObject = Lazy<LargeObject>(initLargeObject,
//                               LazyThreadSafetyMode.ExecutionAndPublication)
lazyLargeObject = New Lazy(Of LargeObject)(AddressOf InitLargeObject)

' The following lines show how to use other constructors to achieve exactly the
' same result as the previous line: 
'lazyLargeObject = New Lazy(Of LargeObject)(AddressOf InitLargeObject, True)
'lazyLargeObject = New Lazy(Of LargeObject)(AddressOf InitLargeObject, _
'                               LazyThreadSafetyMode.ExecutionAndPublication)

Die Factorymethode zeigt die Erstellung des Objekts mit einem Platzhalter für die weitere Initialisierung:

static LargeObject InitLargeObject()
{
    LargeObject large = new LargeObject(Thread.CurrentThread.ManagedThreadId);
    // Perform additional initialization here.
    return large;
}
let initLargeObject () =
    let large = LargeObject Thread.CurrentThread.ManagedThreadId
    // Perform additional initialization here.
    large
Private Shared Function InitLargeObject() As LargeObject
    Dim large As New LargeObject(Thread.CurrentThread.ManagedThreadId)
    ' Perform additional initialization here.
    Return large
End Function

Beachten Sie, dass die ersten beiden Codeabschnitte mithilfe einer Lambda-Funktion kombiniert werden können, wie hier gezeigt:

lazyLargeObject = new Lazy<LargeObject>(() =>
{
    LargeObject large = new LargeObject(Thread.CurrentThread.ManagedThreadId);
    // Perform additional initialization here.
    return large;
});
let lazyLargeObject = Lazy<LargeObject>(fun () ->
    let large = LargeObject Thread.CurrentThread.ManagedThreadId
    // Perform additional initialization here.
    large)
lazyLargeObject = New Lazy(Of LargeObject)(Function () 
    Dim large As New LargeObject(Thread.CurrentThread.ManagedThreadId) 
    ' Perform additional initialization here.
    Return large
End Function)

Das Beispiel hält an, um anzugeben, dass ein unbestimmter Zeitraum vor dem Auftreten der faulen Initialisierung verstrichen sein kann. Wenn Sie die EINGABETASTE Drücken, erstellt und startet das Beispiel drei Threads. Die ThreadProc Methode, die von allen drei Threads verwendet wird, ruft die Value-Eigenschaft auf. Wenn dies zum ersten Mal geschieht, wird die LargeObject Instanz erstellt:

LargeObject large = lazyLargeObject.Value;

// IMPORTANT: Lazy initialization is thread-safe, but it doesn't protect the
//            object after creation. You must lock the object before accessing it,
//            unless the type is thread safe. (LargeObject is not thread safe.)
lock(large)
{
    large.Data[0] = Thread.CurrentThread.ManagedThreadId;
    Console.WriteLine("Initialized by thread {0}; last used by thread {1}.",
        large.InitializedBy, large.Data[0]);
}
let large = lazyLargeObject.Value

// IMPORTANT: Lazy initialization is thread-safe, but it doesn't protect the
//            object after creation. You must lock the object before accessing it,
//            unless the type is thread safe. (LargeObject is not thread safe.)
lock large (fun () ->
    large.Data[0] <- Thread.CurrentThread.ManagedThreadId
    printfn $"Initialized by thread {large.InitializedBy} last used by thread {large.Data[0]}.")
Dim large As LargeObject = lazyLargeObject.Value

' IMPORTANT: Lazy initialization is thread-safe, but it doesn't protect the  
'            object after creation. You must lock the object before accessing it,
'            unless the type is thread safe. (LargeObject is not thread safe.)
SyncLock large
    large.Data(0) = Thread.CurrentThread.ManagedThreadId
    Console.WriteLine("Initialized by thread {0}; last used by thread {1}.", _
        large.InitializedBy, large.Data(0))
End SyncLock

Der Konstruktor der LargeObject-Klasse, die den letzten Schlüsselabschnitt des Codes enthält, zeigt eine Meldung an und zeichnet die Identität des Initialisierungsthreads auf. Die Ausgabe des Programms wird am Ende der vollständigen Codeauflistung angezeigt.

int initBy = 0;
public LargeObject(int initializedBy)
{
    initBy = initializedBy;
    Console.WriteLine("LargeObject was created on thread id {0}.", initBy);
}
type LargeObject(initBy) =
    do 
        printfn $"LargeObject was created on thread id %i{initBy}."
Private initBy As Integer = 0
Public Sub New(ByVal initializedBy As Integer)
    initBy = initializedBy
    Console.WriteLine("LargeObject was created on thread id {0}.", initBy)
End Sub

Anmerkung

Aus Gründen der Einfachheit wird in diesem Beispiel eine globale Instanz von Lazy<T>verwendet, und alle Methoden sind static (Shared in Visual Basic). Dies sind keine Anforderungen für die Verwendung der faulen Initialisierung.

using System;
using System.Threading;

class Program
{
    static Lazy<LargeObject> lazyLargeObject = null;

    static LargeObject InitLargeObject()
    {
        LargeObject large = new LargeObject(Thread.CurrentThread.ManagedThreadId);
        // Perform additional initialization here.
        return large;
    }

    static void Main()
    {
        // The lazy initializer is created here. LargeObject is not created until the
        // ThreadProc method executes.
        lazyLargeObject = new Lazy<LargeObject>(InitLargeObject);

        // The following lines show how to use other constructors to achieve exactly the
        // same result as the previous line:
        //lazyLargeObject = new Lazy<LargeObject>(InitLargeObject, true);
        //lazyLargeObject = new Lazy<LargeObject>(InitLargeObject,
        //                               LazyThreadSafetyMode.ExecutionAndPublication);

        Console.WriteLine(
            "\r\nLargeObject is not created until you access the Value property of the lazy" +
            "\r\ninitializer. Press Enter to create LargeObject.");
        Console.ReadLine();

        // Create and start 3 threads, each of which uses LargeObject.
        Thread[] threads = new Thread[3];
        for (int i = 0; i < 3; i++)
        {
            threads[i] = new Thread(ThreadProc);
            threads[i].Start();
        }

        // Wait for all 3 threads to finish.
        foreach (Thread t in threads)
        {
            t.Join();
        }

        Console.WriteLine("\r\nPress Enter to end the program");
        Console.ReadLine();
    }

    static void ThreadProc(object state)
    {
        LargeObject large = lazyLargeObject.Value;

        // IMPORTANT: Lazy initialization is thread-safe, but it doesn't protect the
        //            object after creation. You must lock the object before accessing it,
        //            unless the type is thread safe. (LargeObject is not thread safe.)
        lock(large)
        {
            large.Data[0] = Thread.CurrentThread.ManagedThreadId;
            Console.WriteLine("Initialized by thread {0}; last used by thread {1}.",
                large.InitializedBy, large.Data[0]);
        }
    }
}

class LargeObject
{
    public int InitializedBy { get { return initBy; } }

    int initBy = 0;
    public LargeObject(int initializedBy)
    {
        initBy = initializedBy;
        Console.WriteLine("LargeObject was created on thread id {0}.", initBy);
    }

    public long[] Data = new long[100000000];
}

/* This example produces output similar to the following:

LargeObject is not created until you access the Value property of the lazy
initializer. Press Enter to create LargeObject.

LargeObject was created on thread id 3.
Initialized by thread 3; last used by thread 3.
Initialized by thread 3; last used by thread 4.
Initialized by thread 3; last used by thread 5.

Press Enter to end the program
 */
open System
open System.Threading

type LargeObject(initBy) =
    do 
        printfn $"LargeObject was created on thread id %i{initBy}."
    member _.InitializedBy = initBy
    member val Data = Array.zeroCreate<int64> 100000000

let initLargeObject () =
    let large = LargeObject Thread.CurrentThread.ManagedThreadId
    // Perform additional initialization here.
    large

// The lazy initializer is created here. LargeObject is not created until the
// ThreadProc method executes.
let lazyLargeObject = Lazy<LargeObject> initLargeObject

// The following lines show how to use other constructors to achieve exactly the
// same result as the previous line:
//     let lazyLargeObject = Lazy<LargeObject>(initLargeObject, true)
//     let lazyLargeObject = Lazy<LargeObject>(initLargeObject,
//                               LazyThreadSafetyMode.ExecutionAndPublication)

let threadProc (state: obj) =
    let large = lazyLargeObject.Value

    // IMPORTANT: Lazy initialization is thread-safe, but it doesn't protect the
    //            object after creation. You must lock the object before accessing it,
    //            unless the type is thread safe. (LargeObject is not thread safe.)
    lock large (fun () ->
        large.Data[0] <- Thread.CurrentThread.ManagedThreadId
        printfn $"Initialized by thread {large.InitializedBy} last used by thread {large.Data[0]}.")

printfn """
LargeObject is not created until you access the Value property of the lazy
initializer. Press Enter to create LargeObject."""
stdin.ReadLine() |> ignore

// Create and start 3 threads, each of which uses LargeObject.

let threads = Array.zeroCreate 3
for i = 0 to 2 do
    threads[i] <- Thread(ParameterizedThreadStart threadProc)
    threads[i].Start()

// Wait for all 3 threads to finish.
for t in threads do
    t.Join()

printfn "\nPress Enter to end the program"
stdin.ReadLine() |> ignore

// This example produces output similar to the following:
//     LargeObject is not created until you access the Value property of the lazy
//     initializer. Press Enter to create LargeObject.
//     
//     LargeObject was created on thread id 3.
//     Initialized by thread 3 last used by thread 3.
//     Initialized by thread 3 last used by thread 4.
//     Initialized by thread 3 last used by thread 5.
//     
//     Press Enter to end the program
Imports System.Threading

Friend Class Program
    Private Shared lazyLargeObject As Lazy(Of LargeObject) = Nothing

    Private Shared Function InitLargeObject() As LargeObject
        Dim large As New LargeObject(Thread.CurrentThread.ManagedThreadId)
        ' Perform additional initialization here.
        Return large
    End Function


    Shared Sub Main()
        ' The lazy initializer is created here. LargeObject is not created until the 
        ' ThreadProc method executes.
        lazyLargeObject = New Lazy(Of LargeObject)(AddressOf InitLargeObject)

        ' The following lines show how to use other constructors to achieve exactly the
        ' same result as the previous line: 
        'lazyLargeObject = New Lazy(Of LargeObject)(AddressOf InitLargeObject, True)
        'lazyLargeObject = New Lazy(Of LargeObject)(AddressOf InitLargeObject, _
        '                               LazyThreadSafetyMode.ExecutionAndPublication)


        Console.WriteLine(vbCrLf & _
            "LargeObject is not created until you access the Value property of the lazy" _
            & vbCrLf & "initializer. Press Enter to create LargeObject.")
        Console.ReadLine()

        ' Create and start 3 threads, each of which uses LargeObject.
        Dim threads(2) As Thread
        For i As Integer = 0 To 2
            threads(i) = New Thread(AddressOf ThreadProc)
            threads(i).Start()
        Next i

        ' Wait for all 3 threads to finish. 
        For Each t As Thread In threads
            t.Join()
        Next t

        Console.WriteLine(vbCrLf & "Press Enter to end the program")
        Console.ReadLine()
    End Sub


    Private Shared Sub ThreadProc(ByVal state As Object)
        Dim large As LargeObject = lazyLargeObject.Value

        ' IMPORTANT: Lazy initialization is thread-safe, but it doesn't protect the  
        '            object after creation. You must lock the object before accessing it,
        '            unless the type is thread safe. (LargeObject is not thread safe.)
        SyncLock large
            large.Data(0) = Thread.CurrentThread.ManagedThreadId
            Console.WriteLine("Initialized by thread {0}; last used by thread {1}.", _
                large.InitializedBy, large.Data(0))
        End SyncLock
    End Sub
End Class

Friend Class LargeObject
    Public ReadOnly Property InitializedBy() As Integer
        Get
            Return initBy
        End Get
    End Property

    Private initBy As Integer = 0
    Public Sub New(ByVal initializedBy As Integer)
        initBy = initializedBy
        Console.WriteLine("LargeObject was created on thread id {0}.", initBy)
    End Sub

    Public Data(99999999) As Long
End Class

' This example produces output similar to the following:
'
'LargeObject is not created until you access the Value property of the lazy
'initializer. Press Enter to create LargeObject.
'
'LargeObject was created on thread id 3.
'Initialized by thread 3; last used by thread 3.
'Initialized by thread 3; last used by thread 5.
'Initialized by thread 3; last used by thread 4.
'
'Press Enter to end the program
'

Hinweise

Verwenden Sie faule Initialisierung, um die Erstellung eines großen oder ressourcenintensiven Objekts oder die Ausführung eines ressourcenintensiven Vorgangs zu verzögern, insbesondere, wenn eine solche Erstellung oder Ausführung während der Lebensdauer des Programms nicht auftritt.

Um sich auf die faule Initialisierung vorzubereiten, erstellen Sie eine Instanz von Lazy<T>. Das Typargument des Lazy<T> Objekts, das Sie erstellen, gibt den Typ des Objekts an, das Sie lazily initialisieren möchten. Der Konstruktor, den Sie zum Erstellen des Lazy<T>-Objekts verwenden, bestimmt die Merkmale der Initialisierung. Lazy initialization occurs the first time the Lazy<T>.Value property is accessed.

In den meisten Fällen hängt die Auswahl eines Konstruktors von Ihren Antworten auf zwei Fragen ab:

  • Wird auf das lazily initialisierte Objekt von mehr als einem Thread zugegriffen? Wenn dies der Fall ist, erstellt das Lazy<T>-Objekt es möglicherweise in einem beliebigen Thread. Sie können einen der einfachen Konstruktoren verwenden, deren Standardverhalten darin besteht, ein threadsicheres Lazy<T>-Objekt zu erstellen, sodass nur eine Instanz des lazily instanziierten Objekts erstellt wird, unabhängig davon, wie viele Threads versuchen, darauf zuzugreifen. Zum Erstellen eines Lazy<T> Objekts, das nicht threadsicher ist, müssen Sie einen Konstruktor verwenden, mit dem Sie keine Threadsicherheit angeben können.

    Vorsicht

    Durch das Schützen des Lazy<T> Objektthreads wird das lazily initialisierte Objekt nicht geschützt. Wenn mehrere Threads auf das lazily initialisierte Objekt zugreifen können, müssen Sie dessen Eigenschaften und Methoden für den Multithreadzugriff sicher machen.

  • Erfordert die faule Initialisierung viel Code, oder verfügt das lazily initialisierte Objekt über einen parameterlosen Konstruktor, der alles benötigt und keine Ausnahmen auslöst? Wenn Sie Initialisierungscode schreiben oder Ausnahmen behandeln müssen, verwenden Sie einen der Konstruktoren, die eine Factorymethode verwenden. Schreiben Sie den Initialisierungscode in der Factorymethode.

In der folgenden Tabelle ist dargestellt, welcher Konstruktor basierend auf diesen beiden Faktoren ausgewählt werden soll:

Der Zugriff auf das Objekt erfolgt über Wenn kein Initialisierungscode erforderlich ist (parameterloser Konstruktor), verwenden Sie Wenn Initialisierungscode erforderlich ist, verwenden Sie
Mehrere Threads Lazy<T>() Lazy<T>(Func<T>)
Ein Thread Lazy<T>(Boolean) mit isThreadSafe auf falsefestgelegt. Lazy<T>(Func<T>, Boolean) mit isThreadSafe auf falsefestgelegt.

Sie können einen Lambda-Ausdruck verwenden, um die Factorymethode anzugeben. Dadurch bleibt der gesamte Initialisierungscode an einer zentralen Stelle. Der Lambda-Ausdruck erfasst den Kontext, einschließlich aller Argumente, die Sie an den Konstruktor des lazily initialisierten Objekts übergeben.

Ausnahmezwischenspeicherung Wenn Sie Factorymethoden verwenden, werden Ausnahmen zwischengespeichert. Wenn die Factorymethode eine Ausnahme auslöst, wenn ein Thread zum ersten Mal versucht, auf die Value-Eigenschaft des Lazy<T> Objekts zuzugreifen, wird bei jedem nachfolgenden Versuch dieselbe Ausnahme ausgelöst. Dadurch wird sichergestellt, dass jeder Aufruf der Value-Eigenschaft dasselbe Ergebnis erzeugt und subtile Fehler vermeidet, die auftreten können, wenn unterschiedliche Threads unterschiedliche Ergebnisse erhalten. Die Lazy<T> steht für eine tatsächliche T, die sonst zu einem früheren Zeitpunkt initialisiert worden wäre, normalerweise während des Starts. Ein Fehler zu diesem früheren Zeitpunkt ist in der Regel tödlich. Wenn es ein Potenzial für einen wiederherstellbaren Fehler gibt, empfiehlt es sich, die Wiederholungslogik in die Initialisierungsroutine zu erstellen (in diesem Fall die Factorymethode), genau wie sie dies wäre, wenn Sie keine faule Initialisierung verwenden würden.

Alternative zum Sperren In bestimmten Situationen sollten Sie den Aufwand des Standardsperrverhaltens des Lazy<T> Objekts vermeiden. In seltenen Situationen kann es ein Potenzial für Deadlocks geben. In solchen Fällen können Sie den Lazy<T>(LazyThreadSafetyMode)- oder Lazy<T>(Func<T>, LazyThreadSafetyMode)-Konstruktor verwenden und LazyThreadSafetyMode.PublicationOnlyangeben. Dadurch kann das Lazy<T>-Objekt eine Kopie des lazily initialisierten Objekts in jedem der verschiedenen Threads erstellen, wenn die Threads die Value Eigenschaft gleichzeitig aufrufen. Das Lazy<T>-Objekt stellt sicher, dass alle Threads dieselbe Instanz des lazily initialisierten Objekts verwenden und die nicht verwendeten Instanzen verwerfen. Die Kosten für die Reduzierung des Sperraufwands sind daher, dass Ihr Programm manchmal zusätzliche Kopien eines teuren Objekts erstellen und verwerfen kann. In den meisten Fällen ist dies unwahrscheinlich. Die Beispiele für die Konstruktoren Lazy<T>(LazyThreadSafetyMode) und Lazy<T>(Func<T>, LazyThreadSafetyMode) veranschaulichen dieses Verhalten.

Wichtig

Wenn Sie LazyThreadSafetyMode.PublicationOnlyangeben, werden Ausnahmen niemals zwischengespeichert, auch wenn Sie eine Factorymethode angeben.

Äquivalente Konstruktoren Zusätzlich zur Aktivierung der Verwendung von LazyThreadSafetyMode.PublicationOnlykönnen die Lazy<T>(LazyThreadSafetyMode) und Lazy<T>(Func<T>, LazyThreadSafetyMode) Konstruktoren die Funktionalität der anderen Konstruktoren duplizieren. In der folgenden Tabelle sind die Parameterwerte aufgeführt, die ein entsprechendes Verhalten erzeugen.

So erstellen Sie ein Lazy<T>-Objekt, das Legen Sie für Konstruktoren mit einem LazyThreadSafetyModemode-Parameter mode auf Legen Sie für Konstruktoren mit einem booleschen isThreadSafe-Parameter isThreadSafe auf Für Konstruktoren ohne Threadsicherheitsparameter
Vollständig threadsicher; verwendet sperren, um sicherzustellen, dass nur ein Thread den Wert initialisiert. ExecutionAndPublication true Alle diese Konstruktoren sind vollständig threadsicher.
Nicht threadsicher. None false Nicht zutreffend.
Vollständig threadsicher; Threads laufen, um den Wert zu initialisieren. PublicationOnly Nicht zutreffend. Nicht zutreffend.

Weitere Funktionen Weitere Informationen zur Verwendung von Lazy<T> mit threadstatischem Feld oder als Sicherungsspeicher für Eigenschaften finden Sie unter Lazy Initialization.

Konstruktoren

Lazy<T>()

Initialisiert eine neue Instanz der Lazy<T> Klasse. Wenn eine faule Initialisierung auftritt, wird der parameterlose Konstruktor des Zieltyps verwendet.

Lazy<T>(Boolean)

Initialisiert eine neue Instanz der Lazy<T> Klasse. Wenn die faule Initialisierung auftritt, werden der parameterlose Konstruktor des Zieltyps und der angegebene Initialisierungsmodus verwendet.

Lazy<T>(Func<T>)

Initialisiert eine neue Instanz der Lazy<T> Klasse. Wenn eine faule Initialisierung auftritt, wird die angegebene Initialisierungsfunktion verwendet.

Lazy<T>(Func<T>, Boolean)

Initialisiert eine neue Instanz der Lazy<T> Klasse. Wenn eine faule Initialisierung auftritt, werden die angegebene Initialisierungsfunktion und der Initialisierungsmodus verwendet.

Lazy<T>(Func<T>, LazyThreadSafetyMode)

Initialisiert eine neue Instanz der Lazy<T> Klasse, die die angegebene Initialisierungsfunktion und den Threadsicherheitsmodus verwendet.

Lazy<T>(LazyThreadSafetyMode)

Initialisiert eine neue Instanz der Lazy<T> Klasse, die den parameterlosen Konstruktor von T und den angegebenen Threadsicherheitsmodus verwendet.

Lazy<T>(T)

Initialisiert eine neue Instanz der Lazy<T> Klasse, die einen präinitialisierten angegebenen Wert verwendet.

Eigenschaften

IsValueCreated

Ruft einen Wert ab, der angibt, ob für diese Lazy<T> Instanz ein Wert erstellt wurde.

Value

Ruft den lazily initialisierten Wert der aktuellen Lazy<T> Instanz ab.

Methoden

Equals(Object)

Bestimmt, ob das angegebene Objekt dem aktuellen Objekt entspricht.

(Geerbt von Object)
GetHashCode()

Dient als Standardhashfunktion.

(Geerbt von Object)
GetType()

Ruft die Type der aktuellen Instanz ab.

(Geerbt von Object)
MemberwiseClone()

Erstellt eine flache Kopie der aktuellen Object.

(Geerbt von Object)
ToString()

Erstellt und gibt eine Zeichenfolgendarstellung der Value -Eigenschaft für diese Instanz zurück.

Gilt für:

Threadsicherheit

Standardmäßig sind alle öffentlichen und geschützten Member der Lazy<T>-Klasse threadsicher und können gleichzeitig aus mehreren Threads verwendet werden. Diese Threadsicherheitsgarantien können optional und pro Instanz mithilfe von Parametern für die Konstruktoren des Typs entfernt werden.

Weitere Informationen