Showing posts with label multithreading. Show all posts
Showing posts with label multithreading. Show all posts

Wednesday, June 18, 2008

Lock-Free Service Locator

Usually, when developing small application there is no real justification for using a full-fledged IoC container for managing services.

However, cross-cutting , single instance services are something common that still has to managed. This leaves us with the following options for accessing services:

  • Implement the service as singleton.
  • Move the service reference between objects.
  • Use a service locator.

I don't like the first option as it introduces global variables to the application and the second option is tedious very hard to manage.

This leaves us with the service locator which in general should be the only singleton(static) in the application and provide access to the services according to their interface.

The service locator usually looks like that:

 

public static class ServiceLocator
{
private static readonly
IDictionary<Type, object> services =
new Dictionary<Type, object>();

private static readonly object locker =
new object();

public static void SetService<T>(T instance)
where T : class
{
if (instance == null)
throw new
ArgumentNullException("instance");

lock (locker)
{
services.Add(
typeof(T), instance);
}
}

public static T GetService<T>() where T : class
{
object service;
lock (locker)
{
services.
TryGetValue(
typeof(T), out service);
}
return service as T;
}
}


 



It hold a dictionary of services. The key is the type and the value is the instance. It is quite simple, however I do not like the fact that it has to lock the services dictionary on each access.



When trying to eliminate the need for locking, I remembered this post by Arnon and it inspired my to try this approach:



public static class ServiceLocator
{
private class Resolver<T> where T:class
{
private static T theInstance;

public static void Create(T instance)
{
if (instance == null)
throw new
ArgumentNullException("instance");

Interlocked.
Exchange(
ref theInstance, instance);
}

public static T Instance
{
get
{
return theInstance;
}
}
}

public static void SetService<T>(T instance)
where T:class
{
Resolver<T>.Create(instance);
}

public static T GetService<T>() where T:class
{
return Resolver<T>.Instance;
}
}



 



Pay attention to the Resolver private class. For every type T that is specified as a generic parameter, a new type, Resolver<SomeType> will be created and the static field, theInstance, will be set to the service instance.



What did we achieve here?



In the previous implementation we had to lock the dictionary on every read or write. In the new implementation there is no need to lock for read and the lock for writing was changed to Interlocked which has better performance so we have better concurrency.



No dictionary. Although it is negligible there is no need to search a dictionary. Besides, I always felt that something like service resolution should be something which is related to the infrastructure and should not be managed by a dictionary and I think this implementation better achieves it.

Thursday, November 22, 2007

Tip of the day: Mutual exclusion when Remoting

Another tip from Gal:"

Just a small tip that might have saved me a few good hours:

A Mutex can be released only by the thread that originally locked it.

A semaphore can be released by any thread.

I used a mutex at the beginning, while locking and releasing on different threads, and at the threadpool desire, got ("sometimes" is the WORST one) an

ApplicationException - Object synchronization method was called from an unsynchronized block of code.

Usually this means that the mutex is not locked but still tries to be released – check this out.

But in my case (first remoting call locks an object and the second releases), it was just that a mutex was the wrong sync method, and a semaphore quickly solved the problem.

As mentioned in the link, the error message need some work."

Wednesday, November 21, 2007

Tip of the day: Interlocked

The Interlocked class in .net is a static class that provides type operation that are performed atomically.

By providing this, it can help solve simple multithreading scenarios since:

1) It removes the chance of deadlocks that can be caused by using the lock keyword.

2) It has better performance than the lock keyword.

3) Simpler (and less) syntax.

Lets take a look at a scenario where you would like to count how many times a method is called while a program runs (multithreaded environment):

private static int methodCallsCounter = 0;
...

public void SomeMethod()
{
System.Threading.Interlocked.
Increment(ref methodCallsCounter);
...
}

The Interlocked class has a set of methods to manipulate data. A complete documentation and a full example can be found here.


Talking about multithreading and locks, I suggest reading this. It describes very important points about locking.