Click here to Skip to main content
Click here to Skip to main content
Go to top

Talkative Locker Pattern

, 25 Nov 2009
Rate this:
Please Sign up or sign in to vote.
A design pattern to help debug multi-threaded applications.

Introduction

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.

Background

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.

Details

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");

        Monitor.Enter(toLock);

        try
        {
            Console.WriteLine(client.Name + ":AquiredLock");
            result = function();
        }
        catch (Exception ex)
        {
            //
        }
        finally
        {
            Console.WriteLine(client.Name + ":About release lock");
            Monitor.Exit(toLock);
        }
        return result;
    }
}

The class 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.

The IClient interface parameter represents the class that will be using the TalkativeLocker class. Here is the code for the interface:

public interface IClient
{
    string Name
    {
        get;
        set;
    }
}

The interface currently only has one property: Name. The 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 = 
                     new TalkativeLocker<int>();

    public Client(string name)
    {
        Name = name;
    }

    public string Name
    {
        get
        {
            return name;
        }
        set
        {
            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[10];

    clients[0] = new Client("1");
    clients[1] = new Client("2");
    clients[2] = new Client("3");
    clients[3] = new Client("4");
    clients[4] = new Client("5");
    clients[5] = new Client("6");
    clients[6] = new Client("7");
    clients[7] = new Client("8");
    clients[8] = new Client("9");
    clients[9] = new Client("10");

    foreach (Client client in clients)
    {
        Thread t = new Thread(client.DoSomething);
        t.Start();
    }

    Thread.CurrentThread.Join();
    Console.ReadLine();
}

Notice that I’ve initialized each client with its own unique ID.

Your output will be the following:

TalkativeLockPattern

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.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

FatCatProgrammer
Software Developer (Senior) Finance Industry
United States United States
Currently pursuing 'Programming Nirvana' (The ineffable ultimate in which one has attained disinterested wisdom and compassion as it relates to programming)
 
Respected Technologies
1. Confusor (https://confuser.codeplex.com/)
2. Power Threading (http://www.wintellect.com/Resources/visit-the-power-threading-library)
3. EDI Parsers (http://www.rdpcrystal.com)
 

Acknowledgements:
 
Microsoft Certified Technologist for WPF and .Net 3.5 (MCTS)
Microsoft Certified Technologist for WCF and .Net 3.5 (MCTS)
Microsoft Certified Application Developer for .Net (MCAD)
Microsoft Certified Systems Engineer (MCSE)
Microsoft Certified Professional (MCP)
 
Sun Certified Developer for Java 2 Platform (SCD)
Sun Certified Programmer for Java 2 Platform (SCP)
Sun Certified Web Component Developer (SCWCD)
 
CompTIA A+ Certified Professional
 
Registered Business School Teacher for Computer Programming and Computer Applications (2004)
(University of the State of New York Education Department)
 
Graduated from University At Stony Brook

Comments and Discussions

 
GeneralExcellent!!! PinmemberAnthonyPaulO23-Dec-09 2:04 
This is a great pattern, I can't believe I hadn't thought about it before! It literally saved my life (I kid you not!) when I was trying to debug a heavily multi-threaded order management system I took over from this brazilian-peruvian genius former co-worker of mine. Apparantly this guy is a .NET God, I mean the code is so beautiful and well organized that it would bring a grown man to tears but the complexity is such that it would bring the Rain Man himself to his knees. Fortunately I found your pattern and was able to finally make some koolaid. Keep up the good work! Big Grin | :-D
 
Anthony
GeneralRe: Excellent!!! PinmemberRelativityE=mc223-Dec-09 6:42 
GeneralRe: Excellent!!! [modified] PinmemberFatCat_Programmer22-Sep-11 11:08 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web02 | 2.8.140916.1 | Last Updated 25 Nov 2009
Article Copyright 2009 by FatCatProgrammer
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid