C#多线程同时访问一个数据对象,如何让一个线程没有阻塞的操作该数据对象
时间: 2024-02-26 20:57:04 浏览: 113
在C#中,要实现多线程同时访问一个数据对象且一个线程没有阻塞的操作该数据对象,可以使用锁或者Monitor类来实现。
下面是一个示例代码,假设有一个共享的数据对象data,同时有两个线程T1和T2需要访问该数据对象,其中T1需要写入数据,T2需要读取数据。我们可以通过实现一个读写锁来实现这个需求:
```csharp
class RWLock
{
private object _lock = new object();
private int _readers = 0;
private bool _writer = false;
public void AcquireReadLock()
{
lock (_lock)
{
while (_writer)
{
Monitor.Wait(_lock);
}
_readers++;
}
}
public void ReleaseReadLock()
{
lock (_lock)
{
_readers--;
if (_readers == 0)
{
Monitor.Pulse(_lock);
}
}
}
public void AcquireWriteLock()
{
lock (_lock)
{
while (_writer || _readers > 0)
{
Monitor.Wait(_lock);
}
_writer = true;
}
}
public void ReleaseWriteLock()
{
lock (_lock)
{
_writer = false;
Monitor.PulseAll(_lock);
}
}
}
class Program
{
static RWLock _lock = new RWLock();
static int data = 0;
static void Main(string[] args)
{
Thread t1 = new Thread(() =>
{
while (true)
{
_lock.AcquireWriteLock();
data++;
_lock.ReleaseWriteLock();
Thread.Sleep(1000);
}
});
Thread t2 = new Thread(() =>
{
while (true)
{
_lock.AcquireReadLock();
Console.WriteLine("data = " + data);
_lock.ReleaseReadLock();
Thread.Sleep(1000);
}
});
t1.Start();
t2.Start();
t1.Join();
t2.Join();
}
}
```
在这个示例代码中,我们定义了一个读写锁RWLock,其中有AcquireReadLock、ReleaseReadLock、AcquireWriteLock和ReleaseWriteLock四个方法。当一个线程需要读取数据时,调用AcquireReadLock方法获取读取锁,然后执行读取操作,最后调用ReleaseReadLock方法释放读取锁。当一个线程需要写入数据时,调用AcquireWriteLock方法获取写入锁,然后执行写入操作,最后调用ReleaseWriteLock方法释放写入锁。
在Main方法中,我们启动了两个线程T1和T2,其中T1需要写入数据,T2需要读取数据。在T1中,我们不断地写入数据,每写入一次就休眠一秒钟。在T2中,我们不断地读取数据,并输出到控制台上,每读取一次就休眠一秒钟。由于我们使用了读写锁,因此T1和T2可以同时访问数据对象data,且一个线程没有阻塞的操作该数据对象。
阅读全文