The Artima Developer Community
Sponsored Link

.NET Buzz Forum
Update of ThreadSafeQueue - don't multi-thread without it

0 replies on 1 page.

Welcome Guest
  Sign In

Go back to the topic listing  Back to Topic List Click to reply to this topic  Reply to this Topic Click to search messages in this forum  Search Forum Click for a threaded view of the topic  Threaded View   
Previous Topic   Next Topic
Flat View: This topic has 0 replies on 1 page
Udi Dahan

Posts: 882
Nickname: udidahan
Registered: Nov, 2003

Udi Dahan is The Software Simplist
Update of ThreadSafeQueue - don't multi-thread without it Posted: May 18, 2005 4:23 PM
Reply to this message Reply

This post originated from an RSS feed registered with .NET Buzz by Udi Dahan.
Original Post: Update of ThreadSafeQueue - don't multi-thread without it
Feed Title: Udi Dahan - The Software Simplist
Feed URL: http://feeds.feedburner.com/UdiDahan-TheSoftwareSimplist
Feed Description: I am a software simplist. I make this beast of architecting, analysing, designing, developing, testing, managing, deploying software systems simple. This blog is about how I do it.
Latest .NET Buzz Posts
Latest .NET Buzz Posts by Udi Dahan
Latest Posts From Udi Dahan - The Software Simplist

Advertisement
First, the tests:
[TestFixture]
	public class QueueTests
	{
		private IQueue q;
		private ManualResetEvent flag;

		[SetUp]
		public void Setup()
		{
			q = new ThreadSafeQueue();
			flag = new ManualResetEvent(false);
		}

		[TearDown]
		public void Teardown()
		{
			flag.Close();
		}

		[Test]
		public void EnqueueShouldWork()
		{
			q.Enqueue(new object());
		}

		[Test]
		public void DequeueAfterEnqueueShouldReturnTheSameObject()
		{
			object o = new object();

			q.Enqueue(o);
			Assert.AreEqual(o, q.Dequeue());
		}

		#region DequeueOnAnEmptyQueueShouldSleep
		[Test]
		public void DequeueOnAnEmptyQueueShouldSleep()
		{
			Thread t = new Thread(new ThreadStart(DequeueFromEmptyQueue));
			t.Start();

			flag.WaitOne(); // let other thread run
			Thread.Sleep(100);

			Assert.AreEqual(ThreadState.WaitSleepJoin, t.ThreadState);

			t.Abort(); // clean up
		}

		private void DequeueFromEmptyQueue()
		{
			flag.Set();
			q.Dequeue();
		}
		#endregion

		#region EnqueueShouldReleaseSleepingThread
		[Test]
		public void EnqueueShouldReleaseSleepingThread()
		{
			Thread t = new Thread(new ThreadStart(DequeueFromNonEmptyQueue));
			t.Start();

			flag.WaitOne(); // let other thread run
			Thread.Sleep(100);

			Assert.AreEqual(ThreadState.WaitSleepJoin, t.ThreadState);

			flag.Reset();

			q.Enqueue(1);

			flag.WaitOne(); // let other thread finish
			Thread.Sleep(100);

			Assert.IsTrue(true);
		}

		private void DequeueFromNonEmptyQueue()
		{
			flag.Set();
			object o = q.Dequeue();

			flag.Set();

			Assert.AreEqual(1, Convert.ToInt32(o));
		}
		#endregion

	}
Then, the code:
public interface IQueue
	{
		void Enqueue(object o);
		object Dequeue();
	}

	/// 
	/// Summary description for ThreadSafeQueue.
	/// 
	public class ThreadSafeQueue: IQueue
	{
		private System.Collections.Queue q = new System.Collections.Queue();
		private ManualResetEvent newItemEntered = new ManualResetEvent(false);

		public Queue()
		{
		}

		public void Enqueue(object o)
		{
			lock(this)
			{
				q.Enqueue(o);
				newItemEntered.Set();
			}
		}

		public object Dequeue()
		{
			newItemEntered.WaitOne();

			lock(this)
			{
				object result = q.Dequeue();
				if (q.Count == 0)
					newItemEntered.Reset();

				return result;
			}

		}
	}
Think of multi-threaded applications as an architecture of cooperation services, each thread a service. These services will receive messages to perform work from a queue like the one above. Threading is a design issue. The number of threads in a system, their responsibilities, what objects they can access, all these are design issues. Don't mess up your design by allowing a BeginInvoke here, or a Thread.Start there. Don't think that the ThreadPool is your friend. If you didn't knowingly design for a thread to begin execution, your that much closer to a deadlock. The final bonus is performance. If no thread needs to actively wait for another thread, then all threads can work in parallel. Even better, this will scale up nicely with more processors. Better than that, scaling out is a piece of cake by swapping out the in-memory-queue implementation with an out-of-process one. Finally, each part of the system is single threaded. There's no reason to have to ponder reentrant business objects. Oh, and don't multi-thread if you don't have to. :)

Read: Update of ThreadSafeQueue - don't multi-thread without it

Topic: Free songs to download on Amazon Previous Topic   Next Topic Topic: Looking forward to Community Server integration with SharePoint!

Sponsored Links



Google
  Web Artima.com   

Copyright © 1996-2019 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use