多线程

什么是多线程?

多线程就是使程序并发(同时)执行几个操作。

.NET 框架类库在System.Threading 中加入了多线程的能力。因此要在前面加入引用 using System.Threading

Thread 类:创建并控制线程,设置其优先级并获取其状态。

Thread 类的构造方法,主要有2中:Thread thread_name=

Thread(ThreadStart):ThreadStart 委托,它表示此线程开始执行时要调用的方法。适用于无参数的方法。

Thread(ParameterizedThreadStart):ParameterizedThreadStart 委托,它表示此线程开始执行时要调用的方法。适用于有参数传入的方法。

一个普通的 无参 线程操作如下:

[csharp] view plaincopyprint?

01.Thread td = new Thread(xunhuan);//定义一个线程,参数是一个方法,无返回值,采用的是委托

02.

03.//前台线程,所有的线程都执行完了,应用程序才退出,默认的都是前台线程

04.//后台线程,所有的前台线程都执行完了,就退出,不管后台的线程

05.td.IsBackground = true; //设定为后台线程

06.td.Start();//启动线程

Thread td = new Thread(xunhuan);//定义一个线程,参数是一个方法,无返回值,采用的是委托


//前台线程,所有的线程都执行完了,应用程序才退出,默认的都是前台线程

//后台线程,所有的前台线程都执行完了,就退出,不管后台的线程

td.IsBackground = true; //设定为后台线程

td.Start();//启动线程

一个有参的线程如下:

[csharp] view plaincopyprint?

01.Thread ptd = new Thread(showname);//定义个线程,传入的带参数的方法。

02.ptd.IsBackground = true;

03.ptd.Start("lilei");//重载Start方法,传递个参数

Thread ptd = new Thread(showname);//定义个线程,传入的带参数的方法。

ptd.IsBackground = true;

ptd.Start("lilei");//重载Start方法,传递个参数


有参的方法定义,参数objec类型,

[csharp] view plaincopyprint?

01.//线程调用,带多个参数

02. static void shownames(object names)

03. {

04. List list = names as List;

05. foreach (string name in list)

06. {

07. MessageBox.Show(name);

08. }

09.

10. }

//线程调用,带多个参数

static void shownames(object names)

{

List list = names as List;

foreach (string name in list)

{

MessageBox.Show(name);

}


}


------------------------------------------------------------------------线程的状态-----------------------------------------------------------------------


任何时候,线程都要处于某种线程状态中。


新线程在Unstarted状态中开始它的生命周期。在调用Thread类的Start方法之前,会一直保持在Unstarted状态,调用方法之后,就会进入Started状态,并立即将程序的控制权返回调用程序(点了线程调用后,可以立即去干别的事)。然后,调用了Start方法的线程(也就是Started线程)和程序中其他的线程并发执行。


线程的优先级


每个线程都有个优先级,其范围在ThreadPriority.Lowest和ThreadPriority.Highest之间。默认情况下,每个线程的优先级都是Normal。


Windows操作系统支持时间分片(timeslicing)的概念,它的思路是优先级相同的线程共享一个处理器。


------------------------------------------------------------------------线程的同步和类监视器-----------------------------------------------------------------------


通常,多个执行线程要操作共享数据。如果有权访问共享数据的线程只能读取数据,那就不需要阻止多个线程同时访问共享数据。然而,当多个线程共享数据,并且其中一个或多个线程要修改数据时,可能会出现无法预知的结果。如果一个线程正在更新数据,另一个线程也试图更新,那么数据所反映的就第二次更新操作之后的结果。


所以可通过一次只允许一个线程访问用于操作共享数据的代码来解决。其他想要操作数据的线程应该等待。具有排他访问权的线程完成对数据的操作后,等待操作线程的数据可以继续执行。这称为互斥或线程同步。


C#提供了两中解决技术:


1.Monitor类:主要方法(方法传入的参数为objec对象,一般为当前调用的线程):


Monitor.Enter():获取排他锁。


Monitor.Wait():释放对象上的锁并阻止当前线程,直到重新获取该锁。


Monitor.Pulse():通知等待队列中的线程对象状态的改变。


Monitor.Exit():释放排他锁。


2.lock关键字:


在对象前加个lock:


代码示例:Monitor的用法:

[csharp] view plaincopyprint?

01.public class mt

02. {

03. private int age;

04. private int buff = 0;//buff判断内容是否已被更新或提取,0为未更新,1为已更新

05. int Age

06. {

07. get

08. {

09. Monitor.Enter(this);//获取此对象的排他锁

10. if (buff == 0)//若内容为空或未更新就使此线程等待

11. {

12. MessageBox.Show("内容为空或未更新");

13. Monitor.Wait(this);//释放锁并等待

14. }

15. buff--;

16. MessageBox.Show("读取内容");

17. Monitor.Pulse(this); //通知等待队列的线程,此对象状态要更改

18. Monitor.Exit(this);//释放排他锁

19. return age;

20.

21. }

22. set

23. {

24. Monitor.Enter(this);

25. if (buff == 1)

26. {

27. MessageBox.Show("内容还没被读取");

28. Monitor.Wait(this);

29. }

30. buff++;

31. MessageBox.Show("写入内容"+value);

32. age = value;

33. Monitor.Pulse(this);

34. Monitor.Exit(this);

35. }

36. }

37. }

public class mt

{

private int age;

private int buff = 0;//buff判断内容是否已被更新或提取,0为未更新,1为已更新

int Age

{

get

{

Monitor.Enter(this);//获取此对象的排他锁

if (buff == 0)//若内容为空或未更新就使此线程等待

{

MessageBox.Show("内容为空或未更新");

Monitor.Wait(this);//释放锁并等待

}

buff--;

MessageBox.Show("读取内容");

Monitor.Pulse(this); //通知等待队列的线程,此对象状态要更改

Monitor.Exit(this);//释放排他锁

return age;


}

set

{

Monitor.Enter(this);

if (buff == 1)

{

MessageBox.Show("内容还没被读取");

Monitor.Wait(this);

}

buff++;

MessageBox.Show("写入内容"+value);

age = value;

Monitor.Pulse(this);

Monitor.Exit(this);

}

}

}


lock的用法:

[csharp] view plaincopyprint?

01.//lock的用法

02. int Age2

03. {

04. get

05. {

06. lock(this) //开始阶段,自获取了排他锁

07. {

08. if (buff == 0)//若内容为空或未更新就使此线程等待

09. {

10. MessageBox.Show("内容为空或未更新");

11. Monitor.Wait(this);//释放锁并等待

12. }

13. buff--;

14. MessageBox.Show("读取内容");

15. Monitor.Pulse(this); //通知等待队列的线程,此对象状态要更改

16. return age;

17.

18. }//结束阶段,释放了排他锁

19. }

20. set

21. {

22. lock (this)

23. {

24. if (buff == 1)

25. {

26. MessageBox.Show("内容还没被读取");

27. Monitor.Wait(this);

28. }

29. buff++;

30. MessageBox.Show("写入内容" + value);

31. age = value;

32. Monitor.Pulse(this);

33. }

34. }

35.

36. }

//lock的用法

int Age2

{

get

{

lock(this) //开始阶段,自获取了排他锁

{

if (buff == 0)//若内容为空或未更新就使此线程等待

{

MessageBox.Show("内容为空或未更新");

Monitor.Wait(this);//释放锁并等待

}

buff--;

MessageBox.Show("读取内容");

Monitor.Pulse(this); //通知等待队列的线程,此对象状态要更改

return age;


}//结束阶段,释放了排他锁

}

set

{

lock (this)

{

if (buff == 1)

{

MessageBox.Show("内容还没被读取");

Monitor.Wait(this);

}

buff++;

MessageBox.Show("写入内容" + value);

age = value;

Monitor.Pulse(this);

}

}


}


-----------------------------------------------------------------lock 与 Monitor 的注意事项------------------------------------------------------------------


Monitor注意的地方:用Monitor类的Enter方法和Exit方法来管理对象的锁时,要想释放锁,必须显示调用Exit方法。调用Exit方法之前如果某个方法中引发了一个异常,并且这个异常没有被捕捉到,方法就会终止,而且不会调用Exit方法。因此锁没有被释放。为了避免这种错误,可以将可能引发异常的代码放入一个try模块,并将对Exit方法的调用放在相应的finally块上以确保释放锁。


使用一个Lock块来管理同步对象上的锁,可以避免忘记调用Monitor类的Exit方法来释放锁。Lock处于某种原因二终止时,C#会隐式调用Monitor类的exit方法。如此一来,即使在代码中出现异常,也可以将锁释放。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
水资源是人类社会的宝贵财富,在生活、工农业生产中是不可缺少的。随着世界人口的增长及工农业生产的发展,需水量也在日益增长,水已经变得比以往任何时候都要珍贵。但是,由于人类的生产和生活,导致水体的污染,水质恶化,使有限的水资源更加紧张。长期以来,油类物质(石油类物质和动植物油)一直是水和土壤中的重要污染源。它不仅对人的身体健康带来极大危害,而且使水质恶化,严重破坏水体生态平衡。因此各国都加强了油类物质对水体和土壤的污染的治理。对于水中油含量的检测,我国处于落后阶段,与国际先进水平存在差距,所以难以满足当今技术水平的要求。为了取得具有代表性的正确数据,使分析数据具有与现代测试技术水平相应的准确性和先进性,不断提高分析成果的可比性和应用效果,检测的方法和仪器是非常重要的。只有保证了这两方面才能保证快速和准确地测量出水中油类污染物含量,以达到保护和治理水污染的目的。开展水中油污染检测方法、技术和检测设备的研究,是提高水污染检测的一条重要措施。通过本课题的研究,探索出一套适合我国国情的水质污染现场检测技术和检测设备,具有广泛的应用前景和科学研究价值。 本课题针对我国水体的油污染,探索一套检测油污染的可行方案和方法,利用非分散红外光度法技术,开发研制具有自主知识产权的适合国情的适于野外便携式的测油仪。利用此仪器,可以检测出被测水样中亚甲基、甲基物质和动植物油脂的污染物含量,为我国众多的环境检测站点监测水体的油污染状况提供依据。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值