Java Mutex锁:别让线程打架,否则程序哭给你看
线程,它属于进程的独立执行单元, 任何一个进程当中都存在着一个主线程, 除开那个主线程之外能够含有别的线程。
采用多线程的意义在于, 它能够对程序的总体响应性起到助力改善的作用, 还可以提升CPU的效率。
多线程之下的应用程序域具备较强的不稳定性, 原因在于有大量线程能于同一时刻里运行共享的功能模块。基于守护应用程序资源免遭破坏的原因, 针对多线程程序给出了三种加锁机制, 它们分别是: 类, Lock关键字以及Mutex类。
1. lock
“lock”所达成的功能为: 致使后续接入的线程不至于打断当下的线程, 而是于当前线程完结之后才接着去执行。
应用:
private Object thisLock=new object();
lock(thisLock){
//锁定的代码块
}
注意:避免锁定 类型,否则实例将超出代码的控制范围。
平常会见到的结构, 有lock (this), 还有lock ( ()), 以及lock ("")。
违反这个准则, 要是实例能够被公共访问, 就会出现lock (this) 问题。
要是, 能够被公众访问, 那就会出现, lock ( ()) 这种问题。
任何其他代码, 在进程里使用同一字符串时, 将会共享同一个锁, 因此出现了lock(“”)问题。
较为好的办法是去把定义出来, 用对象来进行锁定, 或者呢, 运用对象变量去对所有实例共同拥有的数据加以保护。
下面举例说明lock的应用:
接下来的示例里头, 创建起了5个次线程, 这些次线程所要达成的任务是, 去输出线程编码, 延迟1秒钟的时间, 而后输出当时的时刻。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
namespace ConsoleApplication5 {
class Program {
static void Main(string[] args) {
Console.WriteLine ("程序开始时间:"+DateTime.Now .ToString());
Example ex=new Example ();
Thread []threads=new Thread[5];
for (int i=0;i<5;i++)
{
threads[i]=new Thread (new ThreadStart(ex.OutPut));
threads[i].Name =string.Format ("Worker thread#{0}",i) ;
}
foreach(Thread t in threads){
t.Start();
}
Console.WriteLine("主线程最后一句代码!"+DateTime.Now.ToString());
}
}
class Example{
private static object thisLock=new object ();
public void OutPut()
{
lock(thisLock){
Console .WriteLine("->{0}",Thread.CurrentThread.Name);
Thread.Sleep(1000);
Console.WriteLine(DateTime.Now);
}
}
}
}
实验结果如下:
图1:加lock
图2:没有lock
以实验结果而言, 能够看出, 添加lock之后, 程序于每次运行时仅容许一个线程开展执行操作, 而且唯有在当前线程完结执行之后, 才可以进行下一个线程的执行, 要是未添加lock, 程序的执行状况凌乱无序, 极易出现阻塞现象。
2.

lock是针对Enter以及Exit的一种封装, 所以类之中Enter()方法与Exit()方法的联合运用能够用lock关键字去替换。
类除了具有lock的功能外,还有以下功能:
对于解决长期处于死等的状况而言, 若存在一个并发情形频繁出现, 而且其持续时长相当长, 此时加以使用的话, 便能极为有效地防控死锁现象或者避免长时间的那种等待情况发生。
Wait()会把对象上的锁给释放掉, 以此来准许别的线程去锁定以及访问这个对象。当有其他线程对这个对象进行访问的时候, 调用线程就会处于等待的状态。脉冲信号是用来告知处于等待状态的线程关于对象状态所发生的更改标点符号。
被称为Pulse(),()的操作, 促使信号朝着一个或者多个处于等待状态的线程发送出去。此信号起到通知等待着的线程有关锁定对象状态已然发生改变的作用, 并且表明锁的所有者做好了释放该锁的准备。处于等待状态的线程会被安置于对象的就绪队列里,用以使得它能够待到最后去接收对象锁。一旦线程成功拥有了锁, 它便能够针对对象的全新状态展开检查, 借此查看是否已然达到其所需要的状态。
注意:Pulse、和Wait方法必须从同步的代码块内调用。
3. Mutex(互斥体)
Mutex有一突出特点, 那就是能够跨越应用程序域边界, 去实现对资源的独占访问, 在此意义上, 它便能被运用于同步不同进程中的线程, 此项功能的达成却是要以牺牲更多系统资源作为代价的。
互斥体Mutex以及事件对象属于内核对象, 运用内核对象来开展线程同步, 线程必然要在用户模式与内核模式之间进行切换, 故而通常效率很低, 然而借助互斥对象和事件对象这类内核对象, 能够于多个进程里的各个线程之间实现同步!
互斥体Mutex就仿佛是一枚接力棒, 唯有拿到接力棒的线程才能够开启跑的动作, 当然啦, 接力棒在同一时刻仅仅归属一个线程( ), 要是这个线程不把接力棒释放掉(Mutex.), 那么其余所有需要借助接力棒来运行的线程唯有干等着瞧热闹。
更多推荐


所有评论(0)