I’ve been reading many of Martin Fowler’s design patterns (and many other design patterns) lately and have come to appreciate them. What I realize is that a design pattern does not necessarily have to be complex to learn, understand, and apply. The pattern just has to solve a particular problem situation. At the very least, the pattern should help the developer create code that is flexible and easy to modify.
Having said that, I have not seen many widespread patterns that approach the topic of helping developers to debug their multi-threaded programs better. We can all agree that debugging multi-threaded code can easily become a nightmare. Tracking down which threads are currently waiting for a lock, which threads are currently executing, and which threads are about to release a lock can be cumbersome.
I wanted to develop a simple design pattern that could make multi-threading debugging much easier for developers. In this article, I introduce the TalkativeLocker Design Pattern.
The TalkativeLocker Pattern is designed to isolate the locking region of the code from the rest of your code. There is a single point where a lock is entered, acquired, and released. In a way, you are really wrapping the area. By isolating this region, you can write logging and debugging information at each point of the locking and execution stages of any thread that enters.
Here is an extremely simple class that demonstrates the TalkativeLocker Pattern:
public class TalkativeLocker<T>
private readonly static object toLock = new object();
public T EnterLock(IClient client, Func<T> function)
T result = default(T);
Console.WriteLine(client.Name + ":Waiting for lock");
Console.WriteLine(client.Name + ":AquiredLock");
result = function();
catch (Exception ex)
Console.WriteLine(client.Name + ":About release lock");
TalkativeLocker contains a private object only used for locking:
toLock. Notice that it is
static. This means that it will be shared. Only one thread at a time will be able to acquire a lock on it.
TalkativeLocker also has a
Func<T> parameter. This parameter represents the procedure to call when the lock is acquired. Developers can use any parameter they wish. I chose
Func<T> for simplicity.
IClient interface parameter represents the class that will be using the
TalkativeLocker class. Here is the code for the interface:
public interface IClient
The interface currently only has one property:
Name property is used by the
TalkativeLocker class to display any information that developers may see fit to make their multi-threading behavior easier while debugging. If there is more than one client thread, the
Name property should be set to a unique value: one that will identify the thread to the developer. Notice the
TalkativeLocker class using the
Name property on the
IClient interface to write out logging information to the console.
Here is a simple class that implements the interface:
public class Client : IClient
private string name = String.Empty;
private readonly TalkativeLocker<int> talkativeLocker =
public Client(string name)
Name = name;
public string Name
name = value;
public int AddTwoNumbers()
return 1 + 2;
public void DoSomething()
int result = talkativeLocker.EnterLock(this, AddTwoNumbers);
And a sample class that demonstrates the TalkativeLocker Design Pattern:
static void Main(string args)
Client clients = new Client;
clients = new Client("1");
clients = new Client("2");
clients = new Client("3");
clients = new Client("4");
clients = new Client("5");
clients = new Client("6");
clients = new Client("7");
clients = new Client("8");
clients = new Client("9");
clients = new Client("10");
foreach (Client client in clients)
Thread t = new Thread(client.DoSomething);
Notice that I’ve initialized each client with its own unique ID.
Your output will be the following:
I can now see each the status of each thread as they contend for the lock, acquire it, and ultimately release it.
Please let me know if the TalkativeLocker Design Pattern has made debugging your multi-threaded code easier.