Last active
December 15, 2015 17:49
-
-
Save leppie/5299147 to your computer and use it in GitHub Desktop.
Explaining thread safety
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Foo | |
{ | |
static string bar; | |
internal static readonly Random RANDOM = new Random(); | |
internal const int SLEEP1 = 10; | |
internal const int SLEEP2 = 25; | |
public void Baz(string value) | |
{ | |
bar = "#1: " + value; | |
Thread.Sleep(RANDOM.Next(SLEEP1)); | |
bar = "#2: " + value; | |
Thread.Sleep(RANDOM.Next(SLEEP2)); | |
Console.WriteLine("ThreadId: {0} bar: {1}", Thread.CurrentThread.ManagedThreadId, bar); | |
} | |
} | |
class Foo2 | |
{ | |
[ThreadStatic] | |
static string bar; | |
static readonly Random RANDOM = Foo.RANDOM; | |
public void Baz(string value) | |
{ | |
bar = "#1: " + value; | |
Thread.Sleep(RANDOM.Next(Foo.SLEEP1)); | |
bar = "#2: " + value; | |
Thread.Sleep(RANDOM.Next(Foo.SLEEP2)); | |
Console.WriteLine("ThreadId: {0} bar: {1}", Thread.CurrentThread.ManagedThreadId, bar); | |
} | |
} | |
class Foo3 | |
{ | |
string bar; | |
static readonly Random RANDOM = Foo.RANDOM; | |
public void Baz(string value) | |
{ | |
bar = "#1: " + value; | |
Thread.Sleep(RANDOM.Next(Foo.SLEEP1)); | |
bar = "#2: " + value; | |
Thread.Sleep(RANDOM.Next(Foo.SLEEP2)); | |
Console.WriteLine("ThreadId: {0} bar: {1}", Thread.CurrentThread.ManagedThreadId, bar); | |
} | |
} | |
class Program | |
{ | |
const int MAXTHREADS = 32; | |
static void Main(string[] args) | |
{ | |
ThreadPool.SetMaxThreads(MAXTHREADS, MAXTHREADS); | |
Console.WriteLine("Sequential"); | |
for (int i = 0; i < MAXTHREADS; i++) | |
{ | |
Payload(i); | |
} | |
Console.WriteLine(); | |
Console.WriteLine("Threaded - Thread Unsafe"); | |
for (int i = 0; i < MAXTHREADS; i++) | |
{ | |
int k = i; | |
ThreadPool.QueueUserWorkItem(s => Payload(k)); | |
} | |
Wait(); | |
Console.WriteLine(); | |
Console.WriteLine("Threaded - Thread Static"); | |
for (int i = 0; i < MAXTHREADS; i++) | |
{ | |
int k = i; | |
ThreadPool.QueueUserWorkItem(s => Payload2(k)); | |
} | |
Wait(); | |
Console.WriteLine(); | |
Console.WriteLine("Threaded - Thread Instance"); | |
for (int i = 0; i < MAXTHREADS; i++) | |
{ | |
int k = i; | |
ThreadPool.QueueUserWorkItem(s => Payload3(k)); | |
} | |
Wait(); | |
Console.WriteLine(); | |
Console.WriteLine("Press ENTER to exit"); | |
Console.ReadLine(); | |
} | |
static void Wait() | |
{ | |
int t, c; | |
do | |
{ | |
ThreadPool.GetAvailableThreads(out t, out c); | |
} | |
while (t < MAXTHREADS); | |
} | |
static void Payload(int i) | |
{ | |
var f = new Foo(); | |
f.Baz(i.ToString()); | |
} | |
static void Payload2(int i) | |
{ | |
var f = new Foo2(); | |
f.Baz(i.ToString()); | |
} | |
static void Payload3(int i) | |
{ | |
var f = new Foo3(); | |
f.Baz(i.ToString()); | |
} | |
} class Foo | |
{ | |
static string bar; | |
static readonly Random RANDOM = new Random(); | |
public void Baz(string value) | |
{ | |
bar = "#1: " + value; | |
Thread.Sleep(RANDOM.Next(100)); | |
bar = "#2: " + value; | |
Thread.Sleep(RANDOM.Next(100)); | |
Console.WriteLine("ThreadId: {0} bar: {1}", Thread.CurrentThread.ManagedThreadId, bar); | |
} | |
} | |
class Foo2 | |
{ | |
[ThreadStatic] | |
static string bar; | |
static readonly Random RANDOM = new Random(); | |
public void Baz(string value) | |
{ | |
bar = "#1: " + value; | |
Thread.Sleep(RANDOM.Next(100)); | |
bar = "#2: " + value; | |
Thread.Sleep(RANDOM.Next(100)); | |
Console.WriteLine("ThreadId: {0} bar: {1}", Thread.CurrentThread.ManagedThreadId, bar); | |
} | |
} | |
class Foo3 | |
{ | |
string bar; | |
static readonly Random RANDOM = new Random(); | |
public void Baz(string value) | |
{ | |
bar = "#1: " + value; | |
Thread.Sleep(RANDOM.Next(100)); | |
bar = "#2: " + value; | |
Thread.Sleep(RANDOM.Next(100)); | |
Console.WriteLine("ThreadId: {0} bar: {1}", Thread.CurrentThread.ManagedThreadId, bar); | |
} | |
} | |
class Program | |
{ | |
static void Main(string[] args) | |
{ | |
ThreadPool.SetMaxThreads(8, 8); | |
Console.WriteLine("Sequential"); | |
for (int i = 0; i < 16; i++) | |
{ | |
Payload(i); | |
} | |
Console.WriteLine(); | |
Console.WriteLine("Threaded - Thread Unsafe"); | |
for (int i = 0; i < 16; i++) | |
{ | |
int k = i; | |
ThreadPool.QueueUserWorkItem(s => Payload(k)); | |
} | |
Wait(); | |
Console.WriteLine(); | |
Console.WriteLine("Threaded - Thread Static"); | |
for (int i = 0; i < 16; i++) | |
{ | |
int k = i; | |
ThreadPool.QueueUserWorkItem(s => Payload2(k)); | |
} | |
Wait(); | |
Console.WriteLine(); | |
Console.WriteLine("Threaded - Thread Instance"); | |
for (int i = 0; i < 16; i++) | |
{ | |
int k = i; | |
ThreadPool.QueueUserWorkItem(s => Payload3(k)); | |
} | |
Console.ReadLine(); | |
} | |
static void Wait() | |
{ | |
int t, c; | |
do | |
{ | |
ThreadPool.GetAvailableThreads(out t, out c); | |
} | |
while (t < 8); | |
} | |
static void Payload(int i) | |
{ | |
var f = new Foo(); | |
f.Baz(i.ToString()); | |
} | |
static void Payload2(int i) | |
{ | |
var f = new Foo2(); | |
f.Baz(i.ToString()); | |
} | |
static void Payload3(int i) | |
{ | |
var f = new Foo3(); | |
f.Baz(i.ToString()); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment