Lazy<T> Klasse

Definition

Stellt Unterstützung für die verzögerte Initialisierung bereit.

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 verzögert initialisiert wird.

Vererbung
Lazy<T>
Abgeleitet
Attribute

Beispiele

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

Hinweis

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. Um zu einem anderen Konstruktor zu wechseln, ändern Sie einfach, welche Konstruktoren kommentiert werden.

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

Im Beispiel wird eine LargeObject-Klasse definiert, die durch einen von mehreren Threads verzögert initialisiert wird. Die vier wichtigsten Codeabschnitte veranschaulichen die Erstellung des Initialisierers, die Factorymethode, die tatsächliche Initialisierung und den Konstruktor der LargeObject Klasse, die eine Meldung anzeigt, wenn das Objekt erstellt wird. Zu Anfang der Main-Methode wird in diesem Beispiel ein threadsicherer verzögerter Initialisierer für LargeObject erstellt:

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 abgelaufen sein kann, bevor die lazy Initialisierung auftritt. 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, der den letzten Schlüsselabschnitt des Codes enthält, zeigt eine Nachricht an und zeichnet die Identität des Initialisierungsthreads auf. Die Ausgabe aus dem Programm wird am Ende des vollständigen Codeeintrags 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

Hinweis

Der Einfachheit halber 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 verzögerten 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 die lazy-Initialisierung, um die Erstellung eines großen oder ressourcenintensiven Objekts oder die Ausführung eines ressourcenintensiven Vorgangs zurückzuweisen, insbesondere, wenn diese Erstellung oder Ausführung während der Lebensdauer des Programms nicht auftritt.

Um sich auf die lazy 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. Die verzögerte Initialisierung tritt beim ersten Zugriff auf die Lazy<T>.Value-Eigenschaft auf.

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, kann das Lazy<T> Objekt es in einem beliebigen Thread erstellen. Sie können einen der einfachen Konstruktoren verwenden, deren Standardverhalten das Erstellen eines threadsicheren Lazy<T> Objekts ist, sodass nur eine Instanz des lazily instanziierten Objekts erstellt wird, unabhängig davon, wie viele Threads versuchen, darauf zuzugreifen. Um ein Lazy<T> Objekt zu erstellen, das nicht threadsicher ist, müssen Sie einen Konstruktor verwenden, mit dem Sie keine Threadsicherheit angeben können.

    Achtung

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

  • Erfordert die lazy Initialisierung viel Code oder hat das lazily initialisierte Objekt einen parameterlosen Konstruktor, der alles benötigt und keine Ausnahmen auslöst? Wenn Sie Initialisierungscode schreiben oder Ausnahmen behandelt werden müssen, verwenden Sie einen der Konstruktoren, die eine Factorymethode verwenden. Schreiben Sie ihren Initialisierungscode in der Factorymethode.

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

Auf das Objekt wird zugegriffen. 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), wobei isThreadSafe auf false festgelegt ist. Lazy<T>(Func<T>, Boolean), wobei isThreadSafe auf false festgelegt ist.

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

Zwischenspeicherung von Ausnahmen 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 dieselbe Ausnahme bei jedem nachfolgenden Versuch 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. Das Lazy<T> steht für eine tatsächliche T , die andernfalls zu einem früheren Zeitpunkt initialisiert worden wäre, in der Regel während des Starts. Ein Fehler an diesem früheren Punkt ist in der Regel tödlich. Wenn ein wiederherstellbarer Fehler auftreten kann, empfehlen wir, die Wiederholungslogik in die Initialisierungsroutine (in diesem Fall die Factorymethode) zu erstellen, genau wie bei der Verwendung der lazy-Initialisierung.

Alternative zum Sperren In bestimmten Situationen sollten Sie den Aufwand des Standardmäßigen Sperrverhaltens des Lazy<T> Objekts vermeiden. In seltenen Situationen könnte es ein Potenzial für Totsperren geben. In solchen Fällen können Sie den oder Lazy<T>(Func<T>, LazyThreadSafetyMode) den Lazy<T>(LazyThreadSafetyMode) Konstruktor verwenden und angebenLazyThreadSafetyMode.PublicationOnly. Dadurch kann das Lazy<T> Objekt eine Kopie des lazily initialisierten Objekts auf jedem von mehreren 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 Instanzen verwerfen, die nicht verwendet werden. Daher ist die Kosten zur Reduzierung des Sperraufwands, dass Ihr Programm manchmal zusätzliche Kopien eines teuren Objekts erstellt und verwerfen kann. In den meisten Fällen ist dies unwahrscheinlich. Die Beispiele für die Lazy<T>(LazyThreadSafetyMode) und Lazy<T>(Func<T>, LazyThreadSafetyMode) Konstruktoren veranschaulichen dieses Verhalten.

Wichtig

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

Äquivalente Konstruktoren Zusätzlich zur Aktivierung der Verwendung von LazyThreadSafetyMode.PublicationOnly, können die und Lazy<T>(Func<T>, LazyThreadSafetyMode) die Lazy<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 lautet Legen Sie mode für Konstruktoren mit einem Parameter fest auf LazyThreadSafetyMode mode Legen Sie isThreadSafe für Konstruktoren mit einem booleschen isThreadSafe Parameter fest auf Für Konstruktoren ohne Threadsicherheitsparameter
Vollthreadsicher; Verwendet die Sperrung, um sicherzustellen, dass nur ein Thread den Wert initialisiert. ExecutionAndPublication true Alle solchen Konstruktoren sind vollständig threadsicher.
Nicht threadsicher. None false Nicht zutreffend
Vollthreadsicher; Threads rennen, um den Wert zu initialisieren. PublicationOnly Nicht zutreffend Nicht zutreffend

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

Konstruktoren

Lazy<T>()

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

Lazy<T>(Boolean)

Initialisiert eine neue Instanz der Lazy<T>-Klasse. Wenn eine verzögerte 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. Bei einer verzögerten Initialisierung wird die angegebene Initialisierungsfunktion verwendet.

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

Initialisiert eine neue Instanz der Lazy<T>-Klasse. Bei einer verzögerten Initialisierung werden die angegebene Initialisierungsfunktion und der angegebene Initialisierungsmodus verwendet.

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

Initialisiert eine neue Instanz der Lazy<T>-Klasse, die die angegebene Initialisierungsfunktion und den angegebenen 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 vorinitialisierten angegebenen Wert verwendet.

Eigenschaften

IsValueCreated

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

Value

Ruft den verzögert initialisierten Wert der aktuellen Lazy<T>-Instanz ab.

Methoden

Equals(Object)

Bestimmt, ob das angegebene Objekt gleich dem aktuellen Objekt ist.

(Geerbt von Object)
GetHashCode()

Fungiert als Standardhashfunktion.

(Geerbt von Object)
GetType()

Ruft den Type der aktuellen Instanz ab.

(Geerbt von Object)
MemberwiseClone()

Erstellt eine flache Kopie des aktuellen Object.

(Geerbt von Object)
ToString()

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

Gilt für

Threadsicherheit

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

Siehe auch