Unity 单例技巧 之 多线程时快速会单例“加锁”

贡献者: qxkzuiai512

Unity 单例技巧 之 多线程时快速会单例“加锁”。在多线程使用中,由于一个单例多线程可共享使用,会造成在一个单例出现多个生成的情况,这是不允许的,为了避免,给单例生成的时候“加锁”,每次只能一个线程使用,即可避免上述情况,本节介绍如何在单例中使用“锁”的简单案例,具体如下

1Lock:1)lock 关键字将语句块标记为临界区,方法是获取给定对象的互斥锁,执行语句,然后释放该锁。此语句的形式如下:Object thisLock = new Object();lock (thisLock){// Critical code section}2)lock 确保当一个线程位于代码的临界区时,另一个线程不进入临界区。如果其他线程试图进入锁定的代码,则它将一直等待(即被阻止),直到该对象被释放。

2volatile:1)volatile 关键字表示字段可能被多个并发执行线程修改。声明为 volatile 的字段不受编译器优化(假定由单个线程访问)的限制。这样可以确保该字段在任何时间呈现的都是最新的值。2)volatile 修饰符通常用于由多个线程访问而不使用 lock 语句(C# 参考)语句对访问进行序列化的字段

3本案例加锁特点:1)Volatile 与 Lock 并用,双重保险;2)双检查加锁模式。在lock之外和之内, instance是否为空的检查。这叫双检查。因为同步控制的时间太长了。双检查能够最高效地实现多线程安全的访问

1打开Unity,新建一个空工程,然后Unity界面如下图

2在工程中新建一个脚本,脚本可以命名为“Sin etonLockTest”,具体如下图

3选中“Sin etonLockTest”脚本,双击脚本或者右键“Open C# Project”,具体如下图

4在打开的“Sin etonLockTest”脚本上进行代码编辑,首先设置一个静态单例变量,注意加上“volatile”修饰,然后设置一个静态锁对象,最后在单例属性中判断单例是否为空,若为空加锁,继续判断单例是否为空,为空则new个单例,具体代码及代码说明如下图

5具体脚本代码如下:using System.Collecti ;using System.Collecti .Generic;using UnityEngine;pu ic class Sin etonLockTest : MonoBeh iour { private static volatile Sin etonLockTest instance; private static object locker = new object(); pu ic static Sin etonLockTest Instance { get { if (instance == null) { lock (locker) { if (instance == null) { instance = new Sin etonLockTest(); } } } return instance; } } }

6脚本编译正确后,回到Unity界面,在场景中新建一个“GameObject”,然后把脚本“Sin etonLockTest”赋给“GameObject”,具体如下图

7这样,就可以在多线程使用中保证一个单例不会被多次new的情况

8到此,《Unity 单例技巧 之 可重用可自动挂载的单例基类》讲解结束,谢谢

若帮到您,还请帮忙投票以帮助到更多的人;若有疑问,请留言

1 2 3 4 5