Thread-safe Lazy initialization examples in C#.
using System;
using System.Diagnostics;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using System.Runtime.InteropServices;
using System.Text;
using System.Collections.Concurrent;
class Program
{
private static void Main(string[] args)
{
ThreadSafeInit();
ThreadLocalLazyInit();
}
//
// Thread-Safe Lazy Initialization
//
// The following example shows that the same Lazy<int> instance has the same value for three separate threads.
// https://docs.microsoft.com/en-us/dotnet/framework/performance/lazy-initialization#thread-safe-initialization
private static void ThreadSafeInit()
{
Console.WriteLine("Thread-Safe Lazy Initialization:");
Console.WriteLine("");
// Initialize the integer to the managed thread id of the
// first thread that accesses the Value property.
Lazy<int> number = new Lazy<int>(() => Thread.CurrentThread.ManagedThreadId);
Thread t1 = new Thread(() => Console.WriteLine("- number on t1 = {0} ThreadID = {1}",
number.Value, Thread.CurrentThread.ManagedThreadId));
t1.Start();
Thread t2 = new Thread(() => Console.WriteLine("- number on t2 = {0} ThreadID = {1}",
number.Value, Thread.CurrentThread.ManagedThreadId));
t2.Start();
Thread t3 = new Thread(() => Console.WriteLine("- number on t3 = {0} ThreadID = {1}", number.Value,
Thread.CurrentThread.ManagedThreadId));
t3.Start();
// Ensure that thread IDs are not recycled if the
// first thread completes before the last one starts.
t1.Join();
t2.Join();
t3.Join();
Console.WriteLine("");
}
//
// Thread-Local Lazy Initialization
//
// The following example demonstrates that every thread that accesses the ThreadLocal<int> instance gets its own unique copy of the data.
// https://docs.microsoft.com/en-us/dotnet/framework/performance/lazy-initialization#thread-local-lazy-initialization
private static void ThreadLocalLazyInit()
{
Console.WriteLine("Thread-Local Lazy Initialization:");
Console.WriteLine("");
// Initialize the integer to the managed thread id on a per-thread basis.
ThreadLocal<int> threadLocalNumber = new ThreadLocal<int>(() => Thread.CurrentThread.ManagedThreadId);
Thread t4 = new Thread(() => Console.WriteLine("- threadLocalNumber on t4 = {0} ThreadID = {1}",
threadLocalNumber.Value, Thread.CurrentThread.ManagedThreadId));
t4.Start();
Thread t5 = new Thread(() => Console.WriteLine("- threadLocalNumber on t5 = {0} ThreadID = {1}",
threadLocalNumber.Value, Thread.CurrentThread.ManagedThreadId));
t5.Start();
Thread t6 = new Thread(() => Console.WriteLine("- threadLocalNumber on t6 = {0} ThreadID = {1}",
threadLocalNumber.Value, Thread.CurrentThread.ManagedThreadId));
t6.Start();
// Ensure that thread IDs are not recycled if the
// first thread completes before the last one starts.
t4.Join();
t5.Join();
t6.Join();
/* Sample Output:
threadLocalNumber on t4 = 14 ThreadID = 14
threadLocalNumber on t5 = 15 ThreadID = 15
threadLocalNumber on t6 = 16 ThreadID = 16
*/
}
}