发文章
发文工具
撰写
网文摘手
文档
视频
思维导图
随笔
相册
原创同步助手
其他工具
图片转文字
文件清理
AI助手
留言交流
多线程的实现1、多线程的实现方式 (一):异步委托(本质是微软会创建一个执行任务的线程,是使用线程池来完成异步任务),实现异步委托的技术大概有三种,投票、等待句柄、异步回调。 1、投票: public delegate int TakesAWhileDelege(int ms);
static void Main(string[] args)
{
TakesAWhileDelege dl=TakesAWhile;
IAsyncResult ar = dl.BeginInvoke(1000,null,null);
while (ar.IsCompleted)
Console.WriteLine("委托执行完成");
}
public static int TakesAWhile(int ms)
Thread.Sleep(50);
return ms;
2、等待句柄(通过AsyncWaitHandle获取委托的等待句柄WaitHandle,通过该句柄的方法WaitOne方法,即阻止当前线程50毫秒,如果超过50毫秒后该委托还没有完成就返回false) public delegate int TakesAWhileDelege(int ms);
TakesAWhileDelege dl = TakesAWhile;
IAsyncResult ar = dl.BeginInvoke(1000, null, null);
while (true)
if (ar.AsyncWaitHandle.WaitOne(50, false))
break;
int result = dl.EndInvoke(ar);
3、异步回调,(t通过BeginInvoke的最后两个参数,一个是回调函数,一个是)
public delegate int TakesAWhileDelege(int ms);
dl.BeginInvoke(1000, completeTake, dl);
Console.WriteLine("adfa");
public static void completeTake(IAsyncResult ar)
//如果 dl.BeginInvoke(1000, completeTake, dl);中的dl是任何一个参数比如2000,那么这里获取就是
//int num = (int)ar.AsyncState; TakesAWhileDelege dlTemp = ar.AsyncState as TakesAWhileDelege;
int result= dlTemp.EndInvoke(ar);
(二):用Thread类创建线程(无参和有参,另外传递参数的另一种方法是构建一个类对象,参数作为类对象的成员,然后定义一个threadClass3方法,用于在构造Thread对象的时候传递在如:Thread thread2 = new Thread(threadClass3)) 我先声明,用Thread类声明的线程默认都是前台线程,即及时main函数执行完毕后,只要有一个前台线程没有完毕,都会不会终止进程,除非你把IsBackground 改为true,改完后则主线程结束,后台线程也跟着结束,不论他有没有执行完毕 1、普通有参和无参 static void Main(string[] args)
Thread thread1 = new Thread(threadClass1) { Name = "11", IsBackground = false };
thread1.Start();
Thread thread2 = new Thread(threadClass2) { IsBackground = true };
thread2.Start(100);
static void threadClass1()
static void threadClass2(object num)
int nums = (int)num;
2、通过构建类对象 public class Mythread {
Private int num; public void Mythread(int num){
This.num=num;}
Public void threadClass3()
//xxxxxxxxxxxxxxxxxxx
}}调用线程的时候,Mythread my1=new Mythread(100);Thread th1=new Thread(my1.threadClass3);3、 thread1.Join(); Join:是值阻塞这个thread1进程,一直等待这个进程完成后,才继续往下执行 thread1.Abort(); Abort:是终止线程(三):线程池(线程池中的线程必须是后台线程,线程池的进程只能用于时间较短的任务,长时间的线程的话最好新建一个线程) 1、没有参数 static void Main(string[] args)
for (int i = 0; i <= 5; i++)
ThreadPool.QueueUserWorkItem(threadClass);
Console.ReadLine();
static void threadClass(object num)
Thread.Sleep(3000);
Console.WriteLine(Thread.CurrentThread.ManagedThreadId );
} 2、有参数 构建一个类,参数作为类的成员 public class MythreadA
private int num=100;
public MythreadA(int numS)
this.num = numS;
public void threadClass3(object N)
Console.WriteLine(Thread.CurrentThread.ManagedThreadId + ":" + num);
}用线程池
MythreadA Mythread1 = new MythreadA(100+i);
//QueueUserWorkItem需要一个WaitCallback委托作为参数,该委托必须要一个object类型参数,如果我们需要传递参数,可以新建一个类。。
ThreadPool.QueueUserWorkItem(Mythread1.threadClass3);
2、同步的实现方式上面说的都是异步的实现,事实上有时候我们也需要不同线程共享文件或者数据,这就需要保证一次只能一个线程访问和改变共享的状态,所以这就要用到同步技术多线程同步技术有:lock、Monitor(lock被编译器解析为Monitor)、Mutex、Semaphore比如:对于同一个对象,我遍历出20个进程,都把该对象传递过去,对该对象的成员num做循环5000次加1操作,此时会出现的问题是,当第一个线程的i等于2000,判断<5000可以进入循环体的时候,突然线程给了第二个线程,第二个线程继续执行它上次在i=1的时候暂停的操作,这时i突然变成2000,相当于少加了1999次。。如果经常发生这种情况,最后的20个线程的总的结果必定小于10000。Lock(锁定)private object o=new objectfor(int i=0;i<5000;i++){ lock(object ) { num++; }}Monitorprivate object o=new objectlock被编译器解析为Monitor,Monitor调用Enter(object )方法,让线程一直等待,直到当前线程被对象锁定,才开始操作,当然不管是运行结束还是触发异常,我们都必须调用Exit(object )方法,当然Monitor优于lock的地方在于他可以设置等待锁定时间,即TryEnter方法例如,设置让线程等待500毫秒,如果发现还被其他线程锁定,就返回lockif为false,bool lockif=false;Monitor.TryEnter(object,500,ref lockif);if(lockif)
{ //执行操作}Mutex(互斥),互斥继承WaitHandle(WaitHandle在异步委托的时候讲过)互斥和Monitor也很类似,也是确保只有一个进程被互斥锁定,区别在于互斥可以跨越
多个进程(注意不是线程)来互斥同步,比如应用程序是否只能启动一个,当然要达到这种效果必须为互斥命名,不命名的互斥不能跨进程。Mutex mymutex = new Mutex(false,"myMutex",out mutexif);
if (!mutexif)
//执行代码
或者******************************
if (mymutex.WaitOne(50))
//终止线程50毫秒,直到该线程已经操作结束
}Semaphore(信号量),也继承WaitHandle信号量类似互斥锁定Mutex,它是一种控制线程数量的互斥锁定,首先先定义一个信号量var semaphore=new SemaphoreSlim(4,4);然后遍历20个进程,把semaphore作为参数传到每一个进程执行的方法里SemaphoreSlim semaphore=o as SemaphoreSlim ;
Bool isCompleted=false;
While(!isCompleted){
//阻止当前进程,一直到他可以进入semaphore信号量内为止 if(semaphore..Wait(600)) { try
}finally
semaphore.Release();//释放一个信号量,当然也可以指定释放几个信号量参数
isCompleted=true;
}else
//4个信号量已经满了,线程继续等待
来自: 昵称10504424 > 《C#》
0条评论
发表
请遵守用户 评论公约
C#线程同步的几种方法
如: Code int i = 0 ;System.Threading.Interlocked.Increment( ref i);Console.WriteLine(i);System.Threading.Interlocked.Decrement...
锁机制与原子操作 <第四篇>
锁机制与原子操作 <第四篇>一、线程同步中的一些概念。class Program { static void Main(string[] args) { //初始化10个线程1去...
C#中使用Monitor类、Lock和Mutex类来同步多线程的执行
其实把lock和Mutex结合起来使用就可以了,改代码如下: private void thread1Func() { for (int count = 0; count <10; count++) { lock (this...
C# 实现多线程的同步方法详解
// 通监视器来创建临界区 static public void DelUser(string name) { try { // 等待线程进入 Monitor.Enter(Names); Names.Remove(name); Console.WriteLine("Del: {0}", Names.Count); M...
C#线程锁(下)
C#线程锁(下)EventWaitHandle 类允许线程通过发信号互相通信。get { if (this._syncRoot == null) { //如果_syncRoot和null相等,将new object赋值给_syncRoot ...
c# 线程同步: 详解lock,monitor,同步事件和等待句柄以及mutex
c# 线程同步: 详解lock,monitor,同步事件和等待句柄以及mutex对于引用类型和非线程安全的资源的同步处理,有四种相关处理:lock关键字,监视器(Monitor), 同步事件和等待句柄, mutex类。public void ...
JVM性能调优入门
-gc -gcoldLGCC最后一次GC发生的原因。线程状态如下:"t2" prio=10 tid=0x00007fc5a8112800 nid=0x5a58 in Object.wait [0x00...
Linux 线程池
Linux下设计一个简单的线程池
thread_id是该线程的ID;min_th_num是线程池中至少存在的线程数,线程池初始化的过程中会创建min_th_num数量的线程;线程池的管理主要是...
微信扫码,在手机上查看选中内容