Skip to content

Instantly share code, notes, and snippets.

@leppie
Last active December 15, 2015 17:49
Show Gist options
  • Save leppie/5299147 to your computer and use it in GitHub Desktop.
Save leppie/5299147 to your computer and use it in GitHub Desktop.
Explaining thread safety
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