这是我的代码片段。我想,一个线程应该可以工作,而不需要等待上一个线程完成。但我意识到所有线程都是串联启动的,我的脉冲调用对它们的工作方式没有任何影响。
class A
{
string path = "file.xml";
static public object _lock = new object();
static private int accessCounter = 0;
public List<T> GetItems()
{
List<T> result = null;
lock (_lock)
{
while (accessCounter < 0)
Monitor.Wait(_lock);
accessCounter++;
Thread.Sleep(1000);
Monitor.Pulse(_lock);
Thread.Sleep(1000);
using (Stream stream = File.OpenRead(path))
{
XmlSerializer serializer = new XmlSerializer(typeof(List<T>), new Type[] { typeof(T) });
result = (List<T>)serializer.Deserialize(stream);
}
accessCounter--;
Monitor.Pulse(_lock);
}
return result;
}
public void AddItem(T item)
{
lock(_lock){if (accessCounter!=0) Monitor.Wait(_lock);
accessCounter = -1;
//some writing ooperations
accessCounter = 0;
}
}
}我知道,如果条件在目前的情况下是无用的,因为它总是正确的。更重要的是,它们应该同时工作,但不起作用。
编辑:此代码以下列方式从不同线程调用:
.....
A a = new A();
var list = a.GetItems();
.....应该是某种写作/阅读障碍。因此,如果线程想要读取并且其他线程已经在读取文件,那么它不必等待其他线程。如果其他线程捕获了*_lock*,则所有读取线程都需要挂起。
发布于 2012-07-24 10:15:33
您的访问柜台检查错了。它应该检查是否大于,而不小于。
while (accessCounter > 0)
Monitor.Wait(_lock);但是,您的代码似乎有点奇怪。访问计数器检查发生在锁定在_lock上的关键线程中,因此无论如何都不可能有超过一个线程正在执行此代码。这就是为什么您的代码不能同时执行的原因。
另外,请注意,Monitor.Wait 会释放当前线程持有的锁--它不会等待锁变得空闲。
发布于 2012-07-24 12:10:47
该框架已经提供了一种锁定机制(实际上是两种),它应该做您想做的事情(即允许许多同时阅读的读者,但写作是排他性的(同时没有其他读者或作者)-- ReaderWriterLock和ReaderWriterLockSlim。
可以将代码修改为以下内容,以利用ReaderWriterLockSlim:
class A
{
private readonly ReaderWriterLockSlim _lock = new ReaderWriterLockSlim();
string path = "file.xml";
static public object _lock = new object();
static private int accessCounter = 0;
public List<T> GetItems()
{
_lock.EnterReadLock();
try
{
using (Stream stream = File.OpenRead(path))
{
var serializer = new XmlSerializer(typeof(List<T>), new[] { typeof(T) });
return (List<T>)serializer.Deserialize(stream);
}
}
finally
{
_lock.ExitReadLock();
}
}
public void AddItem(T item)
{
_lock.EnterWriteLock();
try
{
// Some writing operations
}
finally
{
_lock.ExitWriteLock();
}
}
}同样值得注意的是,这个方法会泄漏内存,因为每次使用XmlSerializer(Type)或XmlSerializer(Type, String)以外的构造函数创建一个新的XmlSerializer(Type, String)。这将导致每次生成和加载一个新的XML序列化程序集,并且这些程序集永远不会被释放。您需要切换到使用上述两个构造函数之一,或者缓存XmlSerializer实例(可能是由typeof(T)键控),这样就不会泄漏内存。
有关更多信息,请参见此处的“动态生成程序集”部分:XmlSerializer文档
https://stackoverflow.com/questions/11628625
复制相似问题