Concurrency and Source Panels
Atomic Ticket
Issue unique ticket numbers from two threads with Interlocked.
interlocked
`Interlocked.Increment` performs a small shared update atomically, so each thread receives a distinct result.
Atomic Ticket
AtomicTicket.cs
Replay: real traced execution (multi-file project)
using System;
using System.Threading;
class Program
{
static int nextTicket;
static int firstTicket;
static int secondTicket;
static void FirstWorker()
{
firstTicket = Interlocked.Increment(ref nextTicket);
}
static void SecondWorker()
{
secondTicket = Interlocked.Increment(ref nextTicket);
}
static void Main()
{
int start = 100;
nextTicket = start;
Thread first = new Thread(FirstWorker);
Thread second = new Thread(SecondWorker);
first.Start();
second.Start();
first.Join();
second.Join();
int issued = nextTicket - start;
Console.WriteLine($"start={start}");
Console.WriteLine($"issued={issued}");
}
}
using System;
using System.Threading;
class Program
{
static int nextTicket;
static int firstTicket;
static int secondTicket;
static void FirstWorker()
{
firstTicket = Interlocked.Increment(ref nextTicket);
}
static void SecondWorker()
{
secondTicket = Interlocked.Increment(ref nextTicket);
}
static void Main()
{
int start = 10;
nextTicket = start;
Thread first = new Thread(FirstWorker);
Thread second = new Thread(SecondWorker);
first.Start();
second.Start();
first.Join();
second.Join();
int issued = nextTicket - start;
Console.WriteLine($"start={start}");
Console.WriteLine($"issued={issued}");
}
}
using System;
using System.Threading;
class Program
{
static int nextTicket;
static int firstTicket;
static int secondTicket;
static void FirstWorker()
{
firstTicket = Interlocked.Increment(ref nextTicket);
}
static void SecondWorker()
{
secondTicket = Interlocked.Increment(ref nextTicket);
}
static void Main()
{
int start = 500;
nextTicket = start;
Thread first = new Thread(FirstWorker);
Thread second = new Thread(SecondWorker);
first.Start();
second.Start();
first.Join();
second.Join();
int issued = nextTicket - start;
Console.WriteLine($"start={start}");
Console.WriteLine($"issued={issued}");
}
}
start ← 100, nextTicket ← 100, first ← System.Threading.Thread
20static void Main()21{22 int start→ 100 = 100; //@start=10, 50023 nextTicket→ 100 = start100;2425 Thread first→ System.Threading.Thread = new Thread(FirstWorker);26 Thread second→ System.Threading.Thread = new Thread(SecondWorker);2728 firstSystem.Threading.Thread.Start();29 secondSystem.Threading.Thread.Start();nextTicket ← 101, firstTicket ← 101
10static void FirstWorker()11{12 firstTicket→ 101 = Interlocked.Increment(ref nextTicket→ 101);13}second.Start();
28first.Start();29secondSystem.Threading.Thread.Start();3031firstSystem.Threading.Thread.Join();32secondSystem.Threading.Thread.Join();nextTicket ← 102, secondTicket ← 102
15static void SecondWorker()16{17 secondTicket→ 102 = Interlocked.Increment(ref nextTicket→ 102);18}issued ← 2
31 first.Join();32 secondSystem.Threading.Thread.Join();3334 int issued→ 2 = nextTicket102 - start100;35 Console.WriteLine($"start={start100}");36 Console.WriteLine($"issued={issued2}");37}outputstart=100 issued=2
start ← 10, nextTicket ← 10, first ← System.Threading.Thread, second ← System.Threading.Thread
20static void Main()21{22 int start→ 10 = 10;23 nextTicket→ 10 = start10;2425 Thread first→ System.Threading.Thread = new Thread(FirstWorker);26 Thread second→ System.Threading.Thread = new Thread(SecondWorker);2728 firstSystem.Threading.Thread.Start();29 secondSystem.Threading.Thread.Start();nextTicket ← 11, firstTicket ← 11
10static void FirstWorker()11{12 firstTicket→ 11 = Interlocked.Increment(ref nextTicket→ 11);13}second.Start();
28first.Start();29secondSystem.Threading.Thread.Start();3031firstSystem.Threading.Thread.Join();32secondSystem.Threading.Thread.Join();nextTicket ← 12, secondTicket ← 12
15static void SecondWorker()16{17 secondTicket→ 12 = Interlocked.Increment(ref nextTicket→ 12);18}issued ← 2
31 first.Join();32 secondSystem.Threading.Thread.Join();3334 int issued→ 2 = nextTicket12 - start10;35 Console.WriteLine($"start={start10}");36 Console.WriteLine($"issued={issued2}");37}outputstart=10 issued=2
start ← 500, nextTicket ← 500, first ← System.Threading.Thread
20static void Main()21{22 int start→ 500 = 500;23 nextTicket→ 500 = start500;2425 Thread first→ System.Threading.Thread = new Thread(FirstWorker);26 Thread second→ System.Threading.Thread = new Thread(SecondWorker);2728 firstSystem.Threading.Thread.Start();29 secondSystem.Threading.Thread.Start();nextTicket ← 501, firstTicket ← 501
10static void FirstWorker()11{12 firstTicket→ 501 = Interlocked.Increment(ref nextTicket→ 501);13}second.Start();
28first.Start();29secondSystem.Threading.Thread.Start();3031firstSystem.Threading.Thread.Join();32secondSystem.Threading.Thread.Join();nextTicket ← 502, secondTicket ← 502
15static void SecondWorker()16{17 secondTicket→ 502 = Interlocked.Increment(ref nextTicket→ 502);18}issued ← 2
31 first.Join();32 secondSystem.Threading.Thread.Join();3334 int issued→ 2 = nextTicket502 - start500;35 Console.WriteLine($"start={start500}");36 Console.WriteLine($"issued={issued2}");37}outputstart=500 issued=2