下面的表格列展了.NET对协调或同步线程动作的可用的工具:

                      简易阻止方法

构成

目的

Sleep

阻止给定的时间周期

Join

等待另一个线程完成

                      锁系统

构成

目的

跨进程?

速度

lock

确保只有一个线程访问某个资源或某段代码。

Mutex

确保只有一个线程访问某个资源或某段代码。可被用于防止一个程序的多个实例同时运行。

中等

Semaphore

确保不超过指定数目的线程访问某个资源或某段代码。

中等

                    信号系统

构成

目的

跨进程?

速度

EventWaitHandle

允许线程等待直到它受到了另一个线程发出信号。

中等

Wait 和 Pulse*

允许一个线程等待直到自定义阻止条件得到满足。

中等

同步要领

阻止(Blocking)

  当一个线程通过上面所列的方式处于等待或暂停的状态,被称为被阻止。一旦被阻止,线程立刻放弃它被分配的CPU时间,将它的ThreadState属性添加为WaitSleepJoin状态,直到停止阻止。停止阻止由以下任一条件触发:

  • 阻止的条件已得到满足
  • 操作超时(如果timeout被指定了)
  • 通过Thread.Interrupt中断了
  • 通过Thread.Abort放弃了

当线程通过(不建议)Suspend 方法暂停,不认为是被阻止了。

休眠 和 轮询

  调用Thread.Sleep阻止当前的线程指定的时间(或者直到中断):

static void Main() {
Thread.Sleep (0); // 释放CPU时间片
Thread.Sleep (1000); // 休眠1000毫秒
Thread.Sleep (TimeSpan.FromHours (1)); // 休眠1小时
Thread.Sleep (Timeout.Infinite); // 休眠直到中断
}

  确切地说,Thread.Sleep放弃了占用CPU,请求不再被分配时间直到超过某个给定的时间。Thread.Sleep(0)放弃CPU的时间刚刚够其它在时间片队列里的活动线程(如果有的话)被执行。

Thread.Sleep在阻止方法中是唯一的暂停捕获Windows Forms程序的Windows消息的方法,在Windows Forms程序中是一个很大的问题,任何对主UI线程的阻止都将使程序失去相应。因此一般避免这样使用,无论信息获取是否被“技术地”暂定与否。线程类同时也提供了一个SpinWait方法,它使用轮询CPU而非放弃CPU时间的方式,保持给定的迭代次数进行“无用地繁忙”。50迭代停顿大约一微秒,一般取决于CPU的速度和负载。从技术上讲,SpinWait并不是一个阻止的方法:一个处于spin-waiting的线程的ThreadState不是WaitSleepJoin状态,并且也不会被其它的线程过早的中断(Interrupt)。SpinWait很少被使用,它的作用是等待一个在极短时间(可能小于一微秒)内可准备好的可预期的资源,而不用调用Sleep方法阻止线程而浪费CPU时间。不过,这种技术的优势只有在多处理器计算机:对单一处理器的电脑,直到轮询的线程结束了它的时间片之前,一个资源没有机会改变状态,这有违它的初衷。并且调用SpinWait经常会花费较长的时间这本身就浪费了CPU时间。

 阻止 vs. 轮询

线程可以等待某个确定的条件来明确轮询使用一个轮询的方式,比如:

while (!proceed);

或者:

while (DateTime.Now < nextStartTime);

  这是非常浪费CPU时间的:对于CLR和操作系统而言,线程进行了一个重要的计算,所以分配了相应的资源!在这种状态

下的轮询线程不算是阻止,不像一个线程等待一个EventWaitHandle(一般使用这样的信号任务来构建)。

阻止和轮询组合使用可以产生一些变换:

while (!proceed) Thread.Sleep (x); // "轮询休眠!"

 x越大,CPU效率越高,折中方案是增大潜伏时间,任何20ms的花费是微不足道的,除非循环中的条件是极其复杂的。

除了稍有延迟,这种轮询和休眠的方式可以结合的非常好,可能它最大的用处在于程序员可以放弃使用复杂的信号结构来工作了。

使用Join等待一个线程完成

可以通过Join方法阻止线程直到另一个线程结束:

class ThreadDemo {

    static void Main() {

    Thread t = new Thread (delegate() { Console.ReadLine();});

    t.Start();

    t.Join(); // 等待直到线程完成

    Console.WriteLine ("Thread t's ReadLine complete!");

    }

}

  Join方法也接收一个使用毫秒或用TimeSpan类的超时参数,当Join超时是返回false,如果线程已终止,则返回true 。

  Join所带的超时参数非常像Sleep方法,实际上下面两行代码几乎差不多:

Thread.Sleep (1000);
Thread.CurrentThread.Join (1000);

  他们的区别明显在于单线程的应用程序域与COM互操作性:在阻止时,Join保持信息捕获,Sleep暂停信息捕获。

C#多线程实践——线程同步的更多相关文章

  1. C#多线程之线程同步篇3

    在上一篇C#多线程之线程同步篇2中,我们主要学习了AutoResetEvent构造.ManualResetEventSlim构造和CountdownEvent构造,在这一篇中,我们将学习Barrier ...

  2. C#多线程之线程同步篇2

    在上一篇C#多线程之线程同步篇1中,我们主要学习了执行基本的原子操作.使用Mutex构造以及SemaphoreSlim构造,在这一篇中我们主要学习如何使用AutoResetEvent构造.Manual ...

  3. C#多线程之线程同步篇1

    在多线程(线程同步)中,我们将学习多线程中操作共享资源的技术,学习到的知识点如下所示: 执行基本的原子操作 使用Mutex构造 使用SemaphoreSlim构造 使用AutoResetEvent构造 ...

  4. 重新想象 Windows 8 Store Apps (46) - 多线程之线程同步: Lock, Monitor, Interlocked, Mutex, ReaderWriterLock

    [源码下载] 重新想象 Windows 8 Store Apps (46) - 多线程之线程同步: Lock, Monitor, Interlocked, Mutex, ReaderWriterLoc ...

  5. 重新想象 Windows 8 Store Apps (47) - 多线程之线程同步: Semaphore, CountdownEvent, Barrier, ManualResetEvent, AutoResetEvent

    [源码下载] 重新想象 Windows 8 Store Apps (47) - 多线程之线程同步: Semaphore, CountdownEvent, Barrier, ManualResetEve ...

  6. IOS 多线程,线程同步的三种方式

    本文主要是讲述 IOS 多线程,线程同步的三种方式,更多IOS技术知识,请登陆疯狂软件教育官网. 一般情况下我们使用线程,在多个线程共同访问同一块资源.为保护线程资源的安全和线程访问的正确性. 在IO ...

  7. 关于Java多线程的线程同步和线程通信的一些小问题(顺便分享几篇高质量的博文)

    Java多线程的线程同步和线程通信的一些小问题(顺便分享几篇质量高的博文) 前言:在学习多线程时,遇到了一些问题,这里我将这些问题都分享出来,同时也分享了几篇其他博客主的博客,并且将我个人的理解也分享 ...

  8. Java:多线程,线程同步,同步锁(Lock)的使用(ReentrantLock、ReentrantReadWriteLock)

    关于线程的同步,可以使用synchronized关键字,或者是使用JDK 5中提供的java.util.concurrent.lock包中的Lock对象.本文探讨Lock对象. synchronize ...

  9. MFC——9.多线程与线程同步

    Lesson9:多线程与线程同步 程序.进程和线程是操作系统的重点,在计算机编程中.多线程技术是提高程序性能的重要手段. 本文主要解说操作系统中程序.进程和线程之间的关系,并通过相互排斥对象和事件对象 ...

随机推荐

  1. CentOS 7 之几个新特性(转)

    上篇我们讲到默认没有ifconfig是centos7的新特性,所以我特意上网搜索了一下其新特性,找到一篇文章,现转过来. centos最小好化安装没有ifconfig命令 刚安装了centos7.0, ...

  2. Serializable序列化

    对象的输入输出流 package file; import java.io.File; import java.io.FileInputStream; import java.io.FileOutpu ...

  3. MySQL添加中文字符集问题 --- java.sql.SQLException: Incorrect string value

    今天在做开关记录的时候,数据库表中description字段用于记录当前版本的描述(需要存储中文),在测试程序的时候发现如果用户输入中文,那么后台会报错.错误信息如下: java.sql.SQLExc ...

  4. 使用Userlock监控用户访问 增强学校网络安全

    随着网络技术的不断进步,一方面,拥有广泛教学资源的各大大中院校纷纷升级校园网络技术,保护学校的网络安全.另一方面,网络安全面临的威胁也层出不穷.面对来自网络内外的安全威胁,负责中小学.大学院校网络安全 ...

  5. 【HDOJ】3316 Mine sweeping

    简单BFS. #include <iostream> #include <cstdio> #include <cstring> #include <cstdl ...

  6. 【HDOJ】4972 A simple dynamic programming problem

    水题. #include <cstdio> #include <cstring> #include <cstdlib> int abs(int x) { ? -x: ...

  7. 设计模式 ( 二十一 ):Vistor访问者模式 -- 行为型

    1.概述 在软件开发过程中,对于系统中的某些对象,它们存储在同一个集合collection中,且具有不同的类型,而且对于该集合中的对象,可以接受一类称为访问者的对象来访问,而且不同的访问者其访问方式有 ...

  8. HDU_2054——A=B问题

    Problem Description Give you two numbers A and B, if A is equal to B, you should print "YES&quo ...

  9. Apache HttpClient组件封装工具类

    package com.mengyao.spider.utils; import java.util.ArrayList;import java.util.HashMap;import java.ut ...

  10. Mitsubish FX 3U PLC 串口 连接单元

    前段时间遇到一个Mitsubish FX 3U PLC ,现将PLC连接单元分享一下,希望对其他人有所启示. unit PLC_MitsubishiFX; interface uses Windows ...