同步机制,实际上是事件驱动机制,意思是让线程平时处于“休眠”状态,除非发生某个事件才触发。
例如一个拷贝文件,拷贝线程完成一个程序块后,再唤醒进程条线程做一个格的填充。 研究多线程的同步机制的必要性在于,多线程同步工作时,如果同时调用相同的资源就可能会出现问题,一般读出是不会有问题的,但是,如果写入(全局变量、数据库),就会发生冲突,甚至产生死锁和竞争问题。
在.NET中,使用ReaderWriterLock()类来实现同步,它有两个重要的方法: AcquireWriterLock(时间) 在该时间内锁定线程; ReleaseWriterLock()释放锁定。 合理的设计,就可以实现同步:
下面是一个例子:
' 新添加的一个命名空间。 Imports System.Threading
Public Class Form1
Inherits System.Windows.Forms.Form
Dim rwl As New ReaderWriterLock() Dim thdProduce As Thread Dim thdConsume As Thread Dim m_iCounter As Integer
' 生产者线程函数 Sub ThreadProduce()
While True
'使用超时值获取阅读锁,Timeout.Infini为无限长等待超时时间 rwl.AcquireWriterLock(Timeout.Infinite) While m_iCounter < 300
m_iCounter += 1
labProduce.Text = m_iCounter.ToString() Thread.Sleep(10) End While '释放阅读锁
rwl.ReleaseWriterLock() End While End Sub
' 消费者线程函数 Sub ThreadConsume()
While True
rwl.AcquireReaderLock(Timeout.Infinite) While m_iCounter > 0
m_iCounter -= 1
labConsume.Text = m_iCounter.ToString() Thread.Sleep(10) End While
rwl.ReleaseReaderLock() End While
End Sub
' 启动线程的运行。
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Button1.Enabled = False Button2.Enabled = True
thdProduce = New Thread(New ThreadStart(AddressOf ThreadProduce)) thdConsume = New Thread(New ThreadStart(AddressOf ThreadConsume)) thdProduce.Start() thdConsume.Start()
End Sub
Private Sub Form1_Closing(ByVal sender As Object, ByVal e As System.ComponentModel.CancelEventArgs) Handles MyBase.Closing
'释放锁,而不管线程取锁的次数如何 rwl.ReleaseLock() Try
'终止线程
thdProduce.Abort()
Catch End Try Try
thdConsume.Abort() Catch End Try End Sub
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
rwl.ReleaseLock() Try
thdProduce.Abort() Catch End Try Try
thdConsume.Abort() Catch End Try End Sub End Class
同样的例子,也可以用C#写出来:
using System;
using System.Drawing;
using System.Collections; using System.ComponentModel; using System.Windows.Forms; using System.Data; // 新添加的一个命名空间。 using System.Threading;
namespace ThreadSync {
/// /// 清理所有正在使用的资源。 ///
protected override void Dispose( bool disposing ) {
if( disposing ) { }
if (components != null) { }
components.Dispose();
public Form1() { }
// Windows 窗体设计器支持所必需的 InitializeComponent();
// TODO: 在 InitializeComponent 调用后添加任何构造函数代码
///
public class Form1 : System.Windows.Forms.Form {
private System.Windows.Forms.Label label1; private System.Windows.Forms.Label label2; private System.Windows.Forms.Button button1; private System.Windows.Forms.Button button2; private System.Windows.Forms.Label labProduce; private System.Windows.Forms.Label labConsume; /// /// 必需的设计器变量。 ///
private System.ComponentModel.Container components = null;
}
base.Dispose( disposing );
/// /// 应用程序的主入口点。 ///
private ReaderWriterLock rwl = new ReaderWriterLock(); private Thread thdProduce = null; private Thread thdConsume = null; private int m_iCounter = 0; // 生产者线程函数
private void ThreadProduce() { }
// 消费者线程函数
private void ThreadConsume() {
while(true) { }
rwl.AcquireReaderLock(Timeout.Infinite); while(m_iCounter > 0) { }
rwl.ReleaseReaderLock();
m_iCounter--;
labConsume.Text = m_iCounter.ToString(); Thread.Sleep(10);
while(true) { }
rwl.AcquireWriterLock(Timeout.Infinite); while(m_iCounter < 300) { }
rwl.ReleaseWriterLock();
m_iCounter++;
labProduce.Text = m_iCounter.ToString(); Thread.Sleep(10);
Application.Run(new Form1());
}
}
}
// 启动线程的运行。
private void button1_Click(object sender, System.EventArgs e) { }
// 停止线程的运行。
private void button2_Click(object sender, System.EventArgs e) { }
private void Form1_Closing(object sender, System.ComponentModel.CancelEventArgs e) { }
rwl.ReleaseLock(); if(thdProduce != null)
thdProduce.Abort(); thdConsume.Abort(); if(thdConsume != null) rwl.ReleaseLock(); if(thdProduce != null)
thdProduce.Abort(); thdProduce = null; if(thdConsume != null)
thdConsume.Abort(); thdConsume = null; button1.Enabled = true; button2.Enabled = false; button1.Enabled = false; button2.Enabled = true;
thdProduce = new Thread(new ThreadStart(this.ThreadProduce)); thdConsume = new Thread(new ThreadStart(this.ThreadConsume)); if(thdProduce != null)
thdProduce.Start(); thdConsume.Start(); if(thdConsume != null)
效果是完全一样的。
C#代码:
ReaderWriterLock rwl=new ReaderWriterLock(); Thread thdProduce; Thread thdConsume; int m_iCounter;
//生产者线程函数 void ThreadProduce() { }
while (true) { }
//使用超时值获取阅读锁,Timeout.Infini为无限长等待超时时间 while (m_iCounter < 300) { }
//释放阅读锁
rwl.ReleaseWriterLock();
m_iCounter += 1;
labProduce.Text = m_iCounter.ToString(); Thread.Sleep(10);
rwl.AcquireWriterLock(Timeout.Infinite);
//消费者线程函数 void ThreadConsume() {
while (true) {
rwl.AcquireReaderLock(Timeout.Infinite); while (m_iCounter > 0) { }
m_iCounter -= 1;
labConsume.Text = m_iCounter.ToString(); Thread.Sleep(10);
}
}
rwl.ReleaseReaderLock();
private void button1_Click(object sender, System.EventArgs e) {
thdProduce = new Thread(new ThreadStart(ThreadProduce)); thdConsume = new Thread(new ThreadStart(ThreadConsume)); thdProduce.Start(); thdConsume.Start();
private void Form1_Closed(object sender, System.EventArgs e) { }
try { } catch{} try { } catch{}
thdConsume.Abort(); thdProduce.Abort();
}
因篇幅问题不能全部显示,请点此查看更多更全内容
Copyright © 2019- azee.cn 版权所有 赣ICP备2024042794号-5
违法及侵权请联系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com
本站由北京市万商天勤律师事务所王兴未律师提供法律服务