I have partial C# code for a blocking queue that looks like this:
private bool flushed;
private object _locker = new object();
public bool Flushed
{
get { lock (_locker) { return flushed; } }
set
{
lock (_locker)
{
flushed = value;
Monitor.Pulse(queue);
}
}
}
The Monitor.Pulse method has a Monitor.Wait counterpart in the Dequeue() method of the blocking queue.
I want to add a method that signals end of data, which checks for the Flush condition. It will look something like this:
public bool EndOfData
{
get { lock (_locker) { return Flushed && (queue.Count == 0); } }
}
Here is my question. Should I call the Flushed property as shown in the code above (taking a nested lock), or is it sufficient to refer to the private member variable flushed directly, as shown below, using only a single lock?
public bool EndOfData
{
get { lock (_locker) { return flushed && (queue.Count == 0); } }
}
I don't think it makes a difference, personally I would use the nested version.
I think if anything changes in the actual property by using it, Flushed, you ensure
that everything is good to go.
But I truly believe this is a preference call.
Related
For sake of practice, I am trying to write a solution to the readers-writers problem.
The expected behavior should be that multiple reads can run concurrently, but writes need to wait for all readers to finish.
My solution is below in Read(), Write() methods, and the book I am referencing suggests Write2() for the writers.
1) I don't entirely understand why they chose to implement this way, specifically why the read lock is trying to be acquired again, after being awoken when numOfReaders == 0.
Is that to give readers priority, if one came right after Write acquired the read lock, and right before it actually wrote anything?
2) Are there any other issues with the my suggested Write implementation?
Thanks!!
class ReaderWriter
{
private int numOfReaders = 0;
private readonly object readLock = new object();
private readonly object writeLock = new object();
public void Read()
{
lock (readLock)
{
this.numOfReaders++;
}
// Read stuff
lock (readLock)
{
this.numOfReaders--;
Monitor.Pulse(readLock);
}
}
// My solution
public void Write()
{
lock (writeLock)
{
lock (readLock)
{
while (this.numOfReaders > 0)
{
Monitor.Wait(readLock);
}
// Write stuff
}
}
}
// Alternative solution
public void Write2()
{
lock (writeLock)
{
bool done = false;
while (!done)
{
lock (readLock)
{
if (this.numOfReaders == 0)
{
// Write stuff
done = true;
}
else
{
while (this.numOfReaders > 0)
{
Monitor.Wait(readLock);
}
}
}
}
}
}
}
I have a number of worker threads that call a common function. I use a lock object as follows:
static object var mylock = new object();
public void myFunction()
{
if (Monitor.TryEnter(mylock, 0))
{
try
{
// Do work
}
finally
{
Monitor.Exit(mylock);
}
}
}
However, before entering myFunction, I would like to know if the object is locked so that I can do something else. So I did:
public bool IsLocked
{
get { return !Monitor.TryEnter(locker); }
}
Will this work, or is it locking the object?
It will lock the object if it isn't locked, and won't release the lock until you call exit. If the lock is already taken by another thread it won't acquire the lock, but if you're making the call on the thread that acquired the lock in the first place then TryEnter will succeed.
To get around this you could use a flag and the interlocked functions:
object var mylock = new object();
long isLocked;
public void myFunction()
{
if (Monitor.TryEnter(mylock, 0))
{
Interlocked.Exchange(ref isLocked, 1);
try
{
// Do work
}
finally
{
Interlocked.Exchange(ref isLocked, 0);
Monitor.Exit(mylock);
}
}
}
public bool IsLocked
{
get { return Interlocked.Read(ref isLocked)==0; }
}
In Java, you can associate multiple Condition objects to a single ReentrantLock. What would the C# equivalent be?
Real-world example: The example implementation in the Java Condition documentation uses two Condition objects, notFull and notEmpty, tied to the same lock. How could that example be translated to C#?
Background: I often find Java code using two Condition objects to signal various states, associated to the same Lock; in C#, it seems that you can either
call Monitor.Enter on an object, and then Monitor.WaitOne/Monitor.Pulse, but that's just one condition.
use multiple Auto/ManualResetEvent objects, but these cannot atomically reacquire a given lock after waiting.
Note: I can think of one way: using Monitor.WaitOne/Monitor.PulseAll on a single object, and checking for the condition after waking up; that's what you do in Java as well to protect against spurious wake-ups. It doesn't really do, though, because it forces you to call PulseAll instead of Pulse, since Pulse might wake up a thread waiting on another condition. Unfortunately, using PulseAll instead of Pulse has performance implications (threads competing for the same lock).
I think if you are doing new development and can do .NET 4 or above, you'll be better served by the new concurrent collection classes, like ConcurrentQueue.
But if you can't make that move, and to strictly answer your question, in .NET this is somewhat simplified imho, to implement a prod/cons pattern you would just do wait and then pulse like below (note that I typed this on notepad)
// max is 1000 items in queue
private int _count = 1000;
private Queue<string> _myQueue = new Queue<string>();
private static object _door = new object();
public void AddItem(string someItem)
{
lock (_door)
{
while (_myQueue.Count == _count)
{
// reached max item, let's wait 'till there is room
Monitor.Wait(_door);
}
_myQueue.Enqueue(someItem);
// signal so if there are therads waiting for items to be inserted are waken up
// one at a time, so they don't try to dequeue items that are not there
Monitor.Pulse(_door);
}
}
public string RemoveItem()
{
string item = null;
lock (_door)
{
while (_myQueue.Count == 0)
{
// no items in queue, wait 'till there are items
Monitor.Wait(_door);
}
item = _myQueue.Dequeue();
// signal we've taken something out
// so if there are threads waiting, will be waken up one at a time so we don't overfill our queue
Monitor.Pulse(_door);
}
return item;
}
Update: To clear up any confusion, note that Monitor.Wait releases a lock, therefore you won't get a deadlock
#Jason If the queue is full and you wake only ONE thread, you are not guaranteed that thread is a consumer. It might be a producer and you get stuck.
I haven't come across much C# code that would want to share state within a lock. Without rolling your own you could use a SemaphoreSlim (but I recommend ConcurrentQueue(T) or BlockingCollection(T)).
public class BoundedBuffer<T>
{
private readonly SemaphoreSlim _locker = new SemaphoreSlim(1,1);
private readonly int _maxCount = 1000;
private readonly Queue<T> _items;
public int Count { get { return _items.Count; } }
public BoundedBuffer()
{
_items = new Queue<T>(_maxCount);
}
public BoundedBuffer(int maxCount)
{
_maxCount = maxCount;
_items = new Queue<T>(_maxCount);
}
public void Put(T item, CancellationToken token)
{
_locker.Wait(token);
try
{
while(_maxCount == _items.Count)
{
_locker.Release();
Thread.SpinWait(1000);
_locker.Wait(token);
}
_items.Enqueue(item);
}
catch(OperationCanceledException)
{
try
{
_locker.Release();
}
catch(SemaphoreFullException) { }
throw;
}
finally
{
if(!token.IsCancellationRequested)
{
_locker.Release();
}
}
}
public T Take(CancellationToken token)
{
_locker.Wait(token);
try
{
while(0 == _items.Count)
{
_locker.Release();
Thread.SpinWait(1000);
_locker.Wait(token);
}
return _items.Dequeue();
}
catch(OperationCanceledException)
{
try
{
_locker.Release();
}
catch(SemaphoreFullException) { }
throw;
}
finally
{
if(!token.IsCancellationRequested)
{
_locker.Release();
}
}
}
}
Question, Let's say I had Thread A and Thread B and both of these needed access to a singleton object and it's properties.
Currently the singleton looks as follows.
public class Singleton{
#region fields
private static Singleton singletonObject;
private double value1= 0;
private double value2= 0;
private double value3= 0;
private double value4= 0;
private object locker = null;
#endregion
// private constructor. This will avoid creating object using new keyword
private Singleton() {
locker = new object();
}
// public method which will be called
public void GetName() {
Console.WriteLine("singleton Object");
}
public static Singleton Instance() {
// this object will be used with lock, so that it will be always one thread which will be executing the code
object instanceLocker = new object();
// put a lock on myObject. We won't be able to use singleTonObject becuase it will be null. lock is to make the object thread safe.
// lock can't be worked with null objects.
lock (instanceLocker) {
// check whether the instance was there. If it's not there, then create an instance.
if (singletonObject == null) {
singletonObject = new Singleton();
}
}
return singletonObject;
}
public double Value1 { get { lock (locker) { return value1; } } set { lock (locker) { value1= value; } } }
public double Value2 { get { lock (locker) { return value2; } } set { lock (locker) { value2= value; } } }
public double Value3 { get { lock (locker) { return value3; } } set { lock (locker) { value3= value; } } }
public double Value4 { get { lock (locker) { return value4; } } set { lock (locker) { value4= value; } } }
}
My question. Rather than having thread safe properties, is there a better approach?
Thanks,
Currently your code is completely broken. You're creating a new object to lock on during every call. No other thread will ever know about it, so it's completely pointless.
Don't bother trying to fix it in clever ways. Just initialize it in the static variable initializer:
private static Singleton singletonObject = new Singleton();
Nice and simple.
For more information about implementing the singleton pattern in C# (including using Lazy<T> in .NET 4), see my article on the topic.
Aside from the fact that you're creating a new object to lock on for every call, there is another fundamental problem: even if you do have the same object, you're still not really protecting anything.
Somewhere along the line you initialize Value1 to 9:
Singleton.Instance().Value1 = 9;
Now let's say you have two threads executing this code:
public void Foo()
{
Singleton.Instance().Value1++;
if(Singleton.Instance().Value1==10.0)
{
Singleton.Instance().Value2 = 20.0;
}
else
{
Singleton.Instance().Value3 = 30.0;
}
}
Thread A calls Value1++ and incrementing value1 to 10.0
Thread B calls Value1++ and now the value1 is 11.0
Thread A checks if the value value1 is 10.0 -> returns false!
Thread A sets Value3 to 30
Thread B sets Value3 to 30 also.
This is just a very simple example where locking the properties will not protect you since the external code does nothing to guarantee the order in which things are being read or written. There could be a number of other orders in which Thread A and Thread B are executed which will result in completely different outcomes.
This behavior may be OK, since you could have let the user of the Singleton class take the responsibility for ensuring the correct operation outside your class, but it's generally something you should be aware of. Simply locking the properties will not eliminate the read/write contention.
Are you using .NET 4.0? Instead of locking, you can use ConCurrent collections for thread safe activity.
I would like a function to check a Queue for new additions continuously on one thread
Obviously there is the option of a continuous loop with sleeps, but I want something less wasteful.
I considered a wait handle of some type and then having the queue signal it, but I can't override Enqueue safely as it is not virtual.
Now I'm considering encapsulating a Queue<T> as my best option but I wanted to ask you fine folks if there were a better one!
The idea is: I want many threads to access a socket connection while guaranteeing they read only the response for their message, so I was going to have one thread dispatch and read responses and then execute a callback with the response data (in plain text)
Try the blocking queue: Creating a blocking Queue<T> in .NET?
The basic idea is that when you call TryDequeue it will block until there is something in the queue. As you can see "beauty" of the blocking queue is that you don't have to poll/sleep or do anything crazy like that... it's the fundamental backbone for a Producer/Consumer pattern.
My version of the blocking queue is:
public class BlockingQueue<T> where T : class
{
private bool closing;
private readonly Queue<T> queue = new Queue<T>();
public int Count
{
get
{
lock (queue)
{
return queue.Count;
}
}
}
public BlockingQueue()
{
lock (queue)
{
closing = false;
Monitor.PulseAll(queue);
}
}
public bool Enqueue(T item)
{
lock (queue)
{
if (closing || null == item)
{
return false;
}
queue.Enqueue(item);
if (queue.Count == 1)
{
// wake up any blocked dequeue
Monitor.PulseAll(queue);
}
return true;
}
}
public void Close()
{
lock (queue)
{
if (!closing)
{
closing = true;
queue.Clear();
Monitor.PulseAll(queue);
}
}
}
public bool TryDequeue(out T value, int timeout = Timeout.Infinite)
{
lock (queue)
{
while (queue.Count == 0)
{
if (closing || (timeout < Timeout.Infinite) || !Monitor.Wait(queue, timeout))
{
value = default(T);
return false;
}
}
value = queue.Dequeue();
return true;
}
}
public void Clear()
{
lock (queue)
{
queue.Clear();
Monitor.Pulse(queue);
}
}
}
Many thanks to Marc Gravell for this one!