c#多线程

首先说明unity多线程操作的适用范围:

  • 网络请求 
  • 复杂密集的I/O操作
  • 耗时的复杂算法计算(如网格动画)

unity多线程操作的限制:

  • UnityEngine中的API对象不能在子线程中使用(如Unity的组件、对象和系统调用)
  • UnityEngine总定义的基本数据结构可以使用(如vector/quaternion/float/int/struct可以使用)。

总的来说:对于不是画面更新,也不是常规的逻辑更新(指包括AI、物理碰撞、角色控制这些),而是一些其他后台任务,则可以将这个独立出来开辟一个子线程。以此来避免大计算量的运算将主线程卡死的情况。

 

基本函数

  • Start()开始
  • Abort()终止
  • Join()阻塞
  • Sleep()休眠;
using UnityEngine;
using System.Threading;

public class TreadTest : MonoBehaviour
{
    private Thread t0;
    private Thread t1;
    private Thread t2;
    static readonly private Object locker = new Object();

    private int number = 0;
    private void Start()
    {
        t0 = new Thread(TestFunc0);
        t0.Start();
        t1 = new Thread(TestFunc1);
        t1.Start();
        t2 = new Thread(TestFunc2);
        t2.Start();
    }

    private void OnDestroy()
    {
        if (t0 != null)
            t0.Abort();
        if (t1 != null)
            t1.Abort();
        if (t2 != null)
            t2.Abort();
    }

    private void TestFunc0()
    {
        lock (locker)
        {
            number += 1;
            Debug.Log(number);
            t0.Join(1000);
            Thread.Sleep(1000);
        }
    }
    private void TestFunc1()
    {
        lock (locker)
        {
            number += 20;
            Debug.Log(number);
            t1.Join(1000);
            Thread.Sleep(1000);
        }
    }
    private void TestFunc2()
    {
        lock (locker)
        {
            number += 300;
            Debug.Log(number);
            t2.Join(1000);
            Thread.Sleep(1000);
        }
    }
}

lock关键字的作用:

lock事实上就是判断lock对象是否被锁:

  1. 如果没被锁,则往下运行代码,并锁上此锁。
  2. 如果被锁,则挂起该线程,解锁后按情况1处理。

达到的目的即:在多线程环境下,确保lock代码块中的对象只被一个线程操作,从而使得多线程对此对象是顺序访问。

 

lock关键字需要注意的地方有:

lock对象必须是一个不可变对象,否则无法阻止另一个线程进入临界区。最好是static readonly 或者static。

 

常见的lock (this)、lock (typeof (MyType)) 和 lock ("myLock") 都是不合理的写法,其分别的原因是:

  1. lock(this),主要问题是如果类为实例化类,那么this也只是当前实例,不能起到锁定的作用,而且即使是静态类可以被锁定,那么由于尺寸问题,不如锁定不可变小对象合算。
  2. lock(typeof())问题在于锁定对象类型当相于锁定类型中的静态对象部分,锁定了所有实例,速度慢;另一方面,有可能程序其他部分在访问该对象,已经替您锁定,将导致您锁定语句的挂起。
  3. lock("")问题在于微软将内容相同的字符串视为同一个对象,如果您在此锁定了他,那么其实是锁定了同一个对象,将阻止其他地方对字符串的锁定。

实例函数join和静态函数 sleep达成的效果是一致的,皆是在非主线程的线程中调用,静态函数sleep即是挂起当前运行线程。经过试验,实例函数join的实例是哪个thread并不重要,皆是挂起当前运行线程,所以用静态函数sleep就好。

最后分享一篇说sleep说得非常好的文章

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值