jamesm 7/29/2016 0

this is a sample of thread safety sample

 Locking can be used to convert thread-unsafe code into thread-safe code.

Heres an example, where two threads simultaneously add an item to the same List collection, then enumerate the list:

        static List <string> _list = new List <string>();

        static void Main(string[] args)
            new Thread (AddItem).Start();
            new Thread (AddItem).Start();


        static void AddItem()
            lock (_list) _list.Add("Item "   _list.Count);
            string[] items;
            lock (_list) items = _list.ToArray();
            foreach (string s in items) Console.WriteLine(s);

In this case, were locking on the _list object itself. If we had two interrelated lists, we would have to choose a
common object upon which to lock (we could nominate one of the lists, or better: use an independent field).

Locking around thread-safe objects

Sometimes you also need to lock around accessing thread-safe objects. To illustrate, imagine that the Frameworks List
class was, indeed, thread-safe, and we want to add an item to a list:
if (!_list.Contains (newItem)) _list.Add (newItem);
Whether or not the list was thread-safe, this statement is certainly not! The whole if statement would have to be
wrapped in a lock in order to prevent preemption in between testing for containership and adding the new item. This
same lock would then need to be used everywhere we modified that list. For instance, the following statement would
also need to be wrapped in the identical lock:

Thread Safety in Application Servers
For example, suppose you have a RetrieveUser method that queries a database:
// User is a custom class with fields for user data
internal User RetrieveUser (int id) { ... }
If this method was called frequently, you could improve performance by caching the results in a static Dictionary.
Heres a solution that takes thread safety into account:

        static class UserCache
            static Dictionary <int, User> _users = new Dictionary< int, User >();
            internal static User GetUser( int id)
                User u = null ;
                lock (_users)
                    if (_users.TryGetValue(id, out u))
                        return u;
                u = RetrieveUser(id); // Method to retrieve from database;
                lock (_users) _users[id] = u;
                return u;

We must, at a minimum, lock around reading and updating the dictionary to ensure thread safety. In this example, we
choose a practical compromise between simplicity and performance in locking. Our design actually creates a very small
potential for inefficiency: if two threads simultaneously called this method with the same previously unretrieved id, the
RetrieveUser method would be called twiceand the dictionary would be updated unnecessarily. Locking once
across the whole method would prevent this, but would create a worse inefficiency: the entire cache would be locked up
for the duration of calling RetrieveUser, during which time other threads would be blocked in retrieving any user.

Report Bug

Please Login to Report Bug

Reported Bugs


Please Login to Comment