Unity 单例技巧 之 多线程时快速会单例“加锁”。在多线程使用中,由于一稍僚敉视个单例多线程可共享使用,会造成在一个单例出现多个生成的情况,这是不允许的,为了避免,给单例生成的时候“加锁惯墀眚篪”,每次只能一个线程使用,即可避免上述情况,本节介绍如何在单例中使用“锁”的简单案例,具体如下
工具/原料
Unity
单例Singleton
Lock
一、基本概念
1、Lock:1)lock 关键字将语句块标记为临界区,方法是畛粳棠奈获取给定对象的互斥锁,执行语句,然后释放该锁。此语句的形式如下:Object this讣嘬铮篌Lock = new Object();lock (thisLock){// Critical code section}2)lock 确保当一个线程位于代码的临界区时,另一个线程不进入临界区。如果其他线程试图进入锁定的代码,则它将一直等待(即被阻止),直到该对象被释放。
2、volatile:1)volatile 关键字釉涑杵抑表示字段可能被多个并发执行线程修改。声明为 volatile 的字段不受编译器优化(假定由单个线程访维咩缡朊问)的限制。这样可以确保该字段在任何时间呈现的都是最新的值。2)volatile 修饰符通常用于由多个线程访问而不使用 lock 语句(C# 参考)语句对访问进行序列化的字段
3、本案例加锁特点:1)Volatile 与 Lock 并用,双重保险;2)双检查加锁模式。在lock之外和之内,我们做了instance是否为空的检查。这叫双检查。因为同步控制的时间太长了。双检查能够最高效地实现多线程安全的访问
二、单例技巧 之 多线程时快速会单例“加锁”
1、打开Unity,新建一个空工程,然后Unity界面如下图
2、在工程中新建一个脚本,脚本可以命名为“SingletonLockTest”,具体如下图
3、选中“SingletonLockTest”脚本,双击脚本或者右键“Open C# Project”,具体如下图
4、在打开的“SingletonLockTest”脚本上进行代码编辑,首先设置一个静态单例变量,注意加上“volatile”修饰,然后设置一个静态锁对象,最后在单例属性中判断单例是否为空,若为空加锁,继续判断单例是否为空,为空则new个单例,具体代码及代码说明如下图
5、具体脚本代码如下:using System.Co盟敢势袂llections;using System.Collections.Ge荏鱿胫协neric;using UnityEngine;public class SingletonLockTest : MonoBehaviour { private static volatile SingletonLockTest instance; private static object locker = new object(); public static SingletonLockTest Instance { get { if (instance == null) { lock (locker) { if (instance == null) { instance = new SingletonLockTest(); } } } return instance; } } }
6、脚本编译正确后,回到Unity界面,在场景中新建一个“GameObject”,然后把脚本“SingletonLockTest”赋给“GameObject”,具体如下图
7、这样,就可以在多线程使用中保证一个单例不会被多次new的情况
8、到此,《Unity 单例技巧 之 可重用可自动挂载的单例基类》讲解结束,谢谢