.Net中多线程类的使用和总结
lock, Monitor, Thread, Join, BackGroundWorker. 消费者和生产者。Async 委托Invoke
TypeHandle中BlockIndex。
http://msdn.microsoft.com/zh-cn/library/ms173179(v=vs.80).aspx
a. lock相当于 Monitor.Enter, Monitor.Exit. 必须lock引用类型对象。
不能lock公共对象,否则实例将超出代码的控制范围,容易引发死锁。 常见的结构 lock (this)、lock (typeof (MyType)) 和 lock ("myLock") 违反此准则:
对于一段代码锁住a,等待b,另一段代码锁住b,等待a,就会产生死锁
lock(thisLock)
{
if (balance >= amount)
{
Console.WriteLine("Balance before Withdrawal : " + balance);
Console.WriteLine("Amount to Withdraw : -" + amount);
balance = balance - amount;
Console.WriteLine("Balance after Withdrawal : " + balance);
return amount;
}
else
{
return 0; // transaction rejected
}
} lock相当于如下:
if(Monitor.TryEnter(m_inputQueue))
{
try
{
m_inputQueue.Enqueue(qValue);
}
finally
{
Monitor.Exit(m_inputQueue);
}
}
Monitor.Enter(x);
try {
// Code that needs to be protected by the monitor.
}
finally {
// Always use Finally to ensure that you exit the Monitor.
// The following line creates another object containing
// the value of x, and throws SynchronizationLockException
// because the two objects do not match.
Monitor.Exit(x);
}
b. volatile关键字 注意下面的private volatile bool _shouldStop; 加volatitle修饰后可以保证多个线程可以安全的访问此bool变量,这里的用bool表示状态是不需要同步的,并不是volatile保证了其原子性,而仅仅是因为他是个简单的bool型变量。votitle本身并不能保证却对的原子性,如果volatile修饰的是复杂一些结构体,类对象,如果不使用线程同步,会产生非预期的中间状态数据。
using System;
using System.Threading; public class Worker
{
// This method will be called when the thread is started.
public void DoWork()
{
while (!_shouldStop)
{
Console.WriteLine("worker thread: working...");
}
Console.WriteLine("worker thread: terminating gracefully.");
}
public void RequestStop()
{
_shouldStop = true;
}
// Volatile is used as hint to the compiler that this data
// member will be accessed by multiple threads.
private volatile bool _shouldStop;
} public class WorkerThreadExample
{
static void Main()
{
// Create the thread object. This does not start the thread.
Worker workerObject = new Worker();
Thread workerThread = new Thread(workerObject.DoWork); // Start the worker thread.
workerThread.Start();
Console.WriteLine("main thread: Starting worker thread..."); // Loop until worker thread activates.
while (!workerThread.IsAlive); // Put the main thread to sleep for 1 millisecond to
// allow the worker thread to do some work:
Thread.Sleep(); // Request that the worker thread stop itself:
workerObject.RequestStop(); // Use the Join method to block the current thread
// until the object's thread terminates.
workerThread.Join();
Console.WriteLine("main thread: Worker thread has terminated.");
}
}
b. ManualResetEvent
doneEvents[i] = new ManualResetEvent(false); // 1. Set event. Raise singal
doneEvents[i].Set(); // 2. Wait the signal until all the events raise the singal.
WaitHandle.WaitAll(doneEvents);
AutoResetEvent, c. ThreadPool线程池
后台执行任务的线程集合,多用于服务器等需要多个线程的场合。为每个请求分配一个线程来执行请求,执行完请求后线程返回到队列等待再次被使用,避免了每个任务创建/销毁新线程的开销。如果请求过来之后没有可用的线程需要进队列排队。
http://msdn.microsoft.com/zh-cn/library/3dasc8as(v=vs.90).aspx
using System;
using System.Threading; public class Fibonacci
{
public Fibonacci(int n, ManualResetEvent doneEvent)
{
_n = n;
_doneEvent = doneEvent;
} // Wrapper method for use with thread pool.
public void ThreadPoolCallback(Object threadContext)
{
int threadIndex = (int)threadContext;
Console.WriteLine("thread {0} started...", threadIndex);
_fibOfN = Calculate(_n);
Console.WriteLine("thread {0} result calculated...", threadIndex);
_doneEvent.Set();
} // Recursive method that calculates the Nth Fibonacci number.
public int Calculate(int n)
{
if (n <= )
{
return n;
} return Calculate(n - ) + Calculate(n - );
} public int N { get { return _n; } }
private int _n; public int FibOfN { get { return _fibOfN; } }
private int _fibOfN; private ManualResetEvent _doneEvent;
} public class ThreadPoolExample
{
static void Main()
{
const int FibonacciCalculations = ; // One event is used for each Fibonacci object
ManualResetEvent[] doneEvents = new ManualResetEvent[FibonacciCalculations];
Fibonacci[] fibArray = new Fibonacci[FibonacciCalculations];
Random r = new Random(); // Configure and launch threads using ThreadPool:
Console.WriteLine("launching {0} tasks...", FibonacciCalculations);
for (int i = ; i < FibonacciCalculations; i++)
{
doneEvents[i] = new ManualResetEvent(false);
Fibonacci f = new Fibonacci(r.Next(,), doneEvents[i]);
fibArray[i] = f;
ThreadPool.QueueUserWorkItem(f.ThreadPoolCallback, i);
} // Wait for all threads in pool to calculation...
WaitHandle.WaitAll(doneEvents);
Console.WriteLine("All calculations are complete."); // Display the results...
for (int i= ; i<FibonacciCalculations; i++)
{
Fibonacci f = fibArray[i];
Console.WriteLine("Fibonacci({0}) = {1}", f.N, f.FibOfN);
}
}
}
e. AutoResetEvent
.Net中多线程类的使用和总结的更多相关文章
- Delphi中线程类TThread实现多线程编程1---构造、析构……
参考:http://www.cnblogs.com/rogee/archive/2010/09/20/1832053.html Delphi中有一个线程类TThread是用来实现多线程编程的,这个绝大 ...
- 转发 Delphi中线程类TThread 实现多线程编程
Delphi中有一个线程类TThread是用来实现多线程编程的,这个绝大多数Delphi书藉都有说到,但基本上都是对TThread类的几个成员作一简单介绍,再说明一下Execute的实现和Synchr ...
- [转] c#中 多线程访问winform控件
原文 c#中多线程访问winform控件的若干问题小结 我们在做winform应用的时候,大部分情况下都会碰到使用多线程控制界面上控件信息的问题.然而我们并不能用传统方法来解决这个问题,下面我将详细的 ...
- delphi 线程教学第四节:多线程类的改进
第四节:多线程类的改进 1.需要改进的地方 a) 让线程类结束时不自动释放,以便符合 delphi 的用法.即 FreeOnTerminate:=false; b) 改造 Create 的参数 ...
- Java进阶(四十二)Java中多线程使用匿名内部类的方式进行创建3种方式
Java中多线程使用匿名内部类的方式进行创建3种方式 package cn.edu.ujn.demo; // 匿名内部类的格式: public class ThreadDemo { public st ...
- java锁与监视器概念 为什么wait、notify、notifyAll定义在Object中 多线程中篇(九)
在Java中,与线程通信相关的几个方法,是定义在Object中的,大家都知道Object是Java中所有类的超类 在Java中,所有的类都是Object,借助于一个统一的形式Object,显然在有些处 ...
- C#中多线程的并行处理
System.Threading.Tasks,在该命名空间下Task是主类,表示一个类的异步的并发的操作,创建并行代码的时候不一定要直接使用Task类,在某些情况下可以直接使用Parallel静态类( ...
- qt中多线程用法总结
1.多线程的理解 在操作系统中线程和进程划分. 操作系统可以同时执行多个任务,每个任务就是进程:进程可以同时执行多个任务,每个任务就是线程. 线程之间相互独立,抢占式执行.对于单核CPU来说同一时刻只 ...
- 通过编写聊天程序来熟悉python中多线程及socket的用法
1.引言 Python中提供了丰富的开源库,方便开发者快速就搭建好自己所需要的应用程序.本文通过编写基于tcp/ip协议的通信程序来熟悉python中socket以及多线程的使用. 2.python中 ...
随机推荐
- iOS禁止多点操作(按钮和Table项)
1)避免同时点击多个按钮: [btn setExclusiveTouch:YES]; 设置确保当btn点击时,其他按钮不响应: (2)避免同时点击UITableView中多个row -(NSIndex ...
- Linux查看哪些进程用了Swap分区
如果系统的物理内存用光了,则会用到swap.系统就会跑得很慢,但仍能运行;如果Swap空间用光了,那么系统就会发生错误.通常会出现“application is out of memory”的错误,严 ...
- JavaScrip book
1.<JavaScript: The Good Parts>中文版:<JavaScript语言精粹>2.<Professional JavaScript for Web ...
- 【Maven】1.使用myecplise配置自己的Maven配置,不使用默认的maven
[好文章]参考地址: http://www.cnblogs.com/luotaoyeah/p/3764533.html ---------------------------------------- ...
- apache只记录指定URI的日志
我的需求是,把类似请求 www.aaa.com/aaa/... 这样的请求才记录日志.在httpd.conf 或者 相关的虚拟主机配置文件中添加SetEnvIf Request_URI "^ ...
- C# this.Invoke()的作用与用法
Invoke()的作用是:在应用程序的主线程上执行指定的委托.一般应用:在辅助线程中修改UI线程( 主线程 )中对象的属性时,调用this.Invoke(); 在多线程编程中,我们经常要在工作线程 ...
- cocos2d-x 2.2.0 图片选中聚焦 ,图片描边 CCClippingNode 实现
效果例如以下图 左边箭头是x方向翻转的.右边箭头有旋转和缩放action. 大概实现方法:用箭头作为遮罩层,底图是一个绘制的矩形,得到一个黄色箭头背景.在用schedule尾随要聚焦箭头动作.这个 ...
- mpush 服务端配置 for windows 服务自动运行
mpush 服务端配置 以下安装部分是参照官方的步骤, 一.安装jdk1.8并配置环境变量 示例: http://www.cnblogs.com/endv/p/6439860.html 二.Wind ...
- 怪异恼人的java.lang.NoClassDefFoundError: com/sun/mail/util/LineInputStream问题的解决
测试以前做的一个邮件发送类,出现以下问题: Exception in thread "main" java.lang.NoClassDefFoundError: com/sun/m ...
- git学习——查看提交历史
git log可以查看提交历史: 用-p选项展开显示每次提交的内容差异,用-2则仅显示最近两次的更新:git log -p -2 在-p选项后面使用--word-diff选项进行单词层面的对比.这其中 ...