使用Mutex类

                class Program
{
static void Main(string[] args)
{
const string MutexName ="CSharpThreadingCookbook";
using (var m = new Mutex(false, MutexName))
{
if (!m.WaitOne(TimeSpan.FromSeconds(5), false))
{
Console.WriteLine("Second instance is running!");
}
else {
Console.WriteLine("Runing!");
Console.ReadLine();
m.ReleaseMutex();
}
}
}
}

当主程序启动时,定义了一个指定名称的互斥量,设置initialowner标志为false。这意味着如果互斥量已经被创建,则允许程序获取该互斥量。如果没有获取到互斥量,程序则简单的显示running,的等待知道按下了任何键,然后释放该互斥量并退出。 如果再运行同样一个程序,则会在5秒内尝试获取互斥量。如果此时在第一个程序中按下了任何键,第二个程序则会开始执行。然而,如果保持等待5秒钟,第二个程序将无法获取到该互斥量。 该方式可用于在不同的程序中同步线程,可被推广到大量的使用场景中。

使用SemaphoreSilm类

            static SemaphoreSlim _semaphore = new SemaphoreSlim(4);

            static void AccessDatabase(string name, int seconds) {
Console.WriteLine("{0} waits to access a database",name);
_semaphore.Wait();
Console.WriteLine("{0} was granted an access to a database",name);
Thread.Sleep(TimeSpan.FromSeconds(seconds));
Console.WriteLine("{0} is completed",name);
_semaphore.Release(); }
             static void Main(string[] args)
{
for (int i = 1; i <= 6; i++) {
string threadName ="Thread" + i;
int secondsToWait = 2 + 2 * i;
var t = new Thread(() => AccessDatabase(threadName, secondsToWait));
t.Start();
}
Console.ReadKey();
}
当主程序启动时,创建了SemaphoreSlim的一个实例,并在其构造函数中指定允许的并发线程数量。然后启动了6个不同名称和不同初始运行时间的线程。每个线程都尝试获取数据库的访问,但是我们借助于信号系统限制了访问数据库的并发数为4个线程。当有4个线程获取数据库的访问后,其他两个线程需要等待,直到之前线程中的某一个完成工作并调用_semaphore.Release方法来发出信号。

使用AutoResetEvent类

            private staticAutoResetEvent _workerEvent=new AutoResetEvent(false);
private staticAutoResetEvent _mainEvent =new AutoResetEvent(false);
static void Process(int seconds)
{
Console.WriteLine("Starting a long running work... ");
Thread.Sleep(TimeSpan.FromSeconds(seconds));
Console.WriteLine("Work is done!");
_workerEvent.Set();
Console.WriteLine("Waiting for a main thread to complete its work");
_mainEvent.WaitOne();
Console.WriteLine("starting second operation... ");
Thread.Sleep(TimeSpan.FromSeconds(seconds));
Console.WriteLine("Work is done!");
_workerEvent.Set();
}
            static void Main(string[] args)
{
var t = new Thread(() => Process(10));
t.Start();
Console.WriteLine("Waiting for a main thread to complete its work");
_workerEvent.WaitOne();
Console.WriteLine("First operation is completed!");
Console.WriteLine("Performing an operation on a main thread");
Thread.Sleep(TimeSpan.FromSeconds(5));
_mainEvent.Set();
Console.WriteLine("Now running the second operation on a second thread");
_workerEvent.WaitOne();
Console.WriteLine("Second operation is completed!");
}
当主程序启动时,定义了两个autoresetEvent实例。其中一个是从子线程向主线程发信号,另一个实例是从主线程向子线程发信息号 。我们向AutoResetEvent构造方法传入false,定义了这两个实例初始状态为unsignaled。这意味着我们任何线程调用这两个对象中的任何一个 waitone方法将会被堵塞,直到我们调用了set方法。如果初试事件为true,那么autoresetEvent实例的状态为sigaled,如果线程调用waitone方法则会立即处理。 然后事件状态自动变为unsignaled,所以需要再对改实例调用一次set方法,以便让其他的线程对该实例调用waitone方法从而继续执行。 然后我们创建了第二个线程,其会执行第一个操作10秒钟,然后等待从第二个线程发出的信号。该信号意味着第一个操作已经完成。现在第二个线程在 等待主线程的信号,我们对主线程做了一些1附加工作,并通过调用_mainEvent.Set方法发送了一个信号。然后等待从第二个线程发出的另一个信号 AutoResetEvent类采用的是内核时间模式,所以等待时间不能太长。使用2.6节中的ManualResetEventslim类更好,因为他使用的是混合模式。

C#线程(二)的更多相关文章

  1. C#中的线程二(Cotrol.BeginInvoke和Control.Invoke)

    C#中的线程二(Cotrol.BeginInvoke和Control.Invoke) 原文地址:http://www.cnblogs.com/whssunboy/archive/2007/06/07/ ...

  2. 【Qt开发】事件循环与线程 二

    事件循环与线程 二 Qt 线程类 Qt对线程的支持已经有很多年了(发布于2000年九月22日的Qt2.2引入了QThread类),Qt 4.0版本的release则对其所有所支持平台默认地是对多线程支 ...

  3. C#中的线程二(BeginInvoke和Invoke)

    近日,被Control的Invoke和BeginInvoke搞的头大,就查了些相关的资料,整理如下.感谢这篇文章对我的理解Invoke和BeginInvoke的真正含义 . (一)Control的In ...

  4. java 线程二

    一.线程的优先级别 线程优先级别的使用范例: 1 package cn.galc.test; 2 3 public class TestThread6 { 4 public static void m ...

  5. java基础学习总结——线程(二)

    一.线程的优先级别

  6. java基础—线程(二)

    一.线程的优先级别

  7. springboot异步线程(二)

    前言 本篇文章针对上篇文章springboot异步线程,有一位大佬在评论中提出第一点是错误的,当时看到了这个问题,最近刚好有空,针对第一点的问题去搜索了不少的文章: 问题 我在文章中第一点去验证:Sc ...

  8. python并发编程之线程(二):死锁和递归锁&信号量&定时器&线程queue&事件evevt

    一 死锁现象与递归锁 进程也有死锁与递归锁,在进程那里忘记说了,放到这里一切说了额 所谓死锁: 是指两个或两个以上的进程或线程在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力作用,它们都将 ...

  9. C#中的线程(二) 线程同步基础

    1.同步要领 下面的表格列展了.NET对协调或同步线程动作的可用的工具:                       简易阻止方法 构成 目的 Sleep 阻止给定的时间周期 Join 等待另一个线程 ...

  10. Linux 进程与线程二(等待--分离--取消线程)

    int pthread_join(pthread_t thr,void **thr_return); pthread_join函数用于挂起当前线程,直至th指定的线程终止为止. 如果另一个线程返回值不 ...

随机推荐

  1. 持续集成篇 --Hudson持续集成服务器的安装配置与使用

    样例项目参考视频教程:http://www.roncoo.com/course/view/85d6008fe77c4199b0cdd2885eaeee53 IP:192.168.4.221  8G内存 ...

  2. 9.Smarty的循环

    1.session循环 目的:循环输出一个二维数组 构造一个二维数组 $towSide = array( array("name"=>"caimuqing" ...

  3. Unity应用架构设计(13)——日志组件的实施

    对于应用程序而言,日志是非常重要的功能,通过日志,我们可以跟踪应用程序的数据状态,记录Crash的日志可以帮助我们分析应用程序崩溃的原因,我们甚至可以通过日志来进行性能的监控.总之,日志的好处很多,特 ...

  4. webpack3中文版使用参考文档--全面解析webpack.config.js

    Webpack目前官方发布的最新版本是3.1.0,相对于2.0的怎么本,在语法上没有变动,只是新增了功能.使用webpack,需要事先安装node.js,并对node.js生态有一些基本的了解,比如( ...

  5. intellij idea 常用快捷键让你事半功倍

    为什么谈这个 工欲善其事必先利其器,键盘流是必须的,快捷键首当其冲,请收下!!! 常用快捷键列表 Live Templates 自定义代码模板 取消屏幕的翻转,可以使用ctrl+alt+左右,进行代码 ...

  6. 使用three.js加载3dmax资源,以及实现场景中的阴影效果

    使用three.js可以方便的让我们在网页中做出各种不同的3D效果.如果希望2D绘图内容,建议使用canvas来进行.但很多小伙伴不清楚到底如何为我们绘制和导入的图形添加阴影效果,更是不清楚到底如何导 ...

  7. Oracle的over子函数的妙用

    摘要 oracle的over 子函数可实现按指定的字段分组排序,对于相同分组字段的结果集进行排序,其中PARTITION BY 为分组字段,ORDER BY 指定排序字段这对统计分析这类问题意想不到的 ...

  8. Unreal Engine 4(虚幻UE4)GameplayAbilities 插件入门教程(四)技能屏蔽和简单的Buff等

    本节内容继续上一节教程的内容(如果没有看过前面的教程,请前往学习),不会讲太难的新东西,而是继续探究技能标签(Abiilty Tags)的内容.先来一道开胃菜. 第1.1步: 将上一次的召唤冰龙中的C ...

  9. Groovy - 介绍

    Groovy 是 用于Java虚拟机的一种敏捷的动态语言,它是一种成熟的面向对象编程语言,既可以用于面向对象编程,又可以用作纯粹的脚本语言.使用该种语言不必编写过多的代码,同时又具有闭包和动态语言中的 ...

  10. 如何写出面试官欣赏的Java单例

    单例模式是一种常用的软件设计模式.在它的核心结构中只包含一个被称为单例的特殊类.通过单例模式可以保证系统中一个类只有一个实例. 今天我们不谈单例模式的用途,只说一说如果在面试的时候面试官让你敲一段代码 ...