简介
自己开始接触一下多线程
Thread
属性:主线程id为1,优先级Lowest,IsThreadPoolThread为false,IsBackground为false一个线程默认占用1M的堆栈空间,也可以修改
属性说明
CurrentThreadManagedThreadIdget 当前线程Nameget;set 线程名称IsBackgroundget;set 是否为后台线程IsThreadPoolThreadget 是否属于托管线程池ManagedThreadIdget 当前托管线程唯一标识符IsAlive当前线程执行状态Priority当前线程调度优先级ThreadState当前线程的状态(运行停止后台禁止…)
方法:
方法说明
Start开启Suspend挂起Resume继续挂起的线程Abort终止Sleep当前线程挂起或阻塞指定时间
简单实例
创建开始,有参函数参数只能有一个,而且是object类型,但是既然都是object了,就可以改变一下传更多参数
void Start () {
InitThread();
Debug.LogError("MainThread:" + Thread.CurrentThread.ManagedThreadId.ToString());
}
private void InitThread()
{
Thread t1 = new Thread(Start1);
t1.Start();
Thread t2 = new Thread(Start2);
t2.Start("LOG");
Thread t3 = new Thread(Start3);
t3.Start(new MoreParams(10086, "hah"));
}
private void Start1()
{
Debug.LogError("Start1:" + Thread.CurrentThread.ManagedThreadId.ToString());
}
//单个参数
private void Start2(object log)
{
Debug.LogError("Start2:" + Thread.CurrentThread.ManagedThreadId.ToString()+log);
}
//多个参数
private void Start3(object p)
{
MoreParams moreparams= (MoreParams)p;
Debug.LogError("Start3:" + Thread.CurrentThread.ManagedThreadId.ToString());
Debug.LogError("p1:" + moreparams.p1 + "_p2:" + moreparams.p2);
}
class MoreParams
{
public int p1;
public string p2;
public MoreParams(int p1, string p2)
{
this.p1 = p1;
this.p2 = p2;
}
}
输出:每次运行,主线程id为1,新线程的id都不同,会累加,输出顺序不固定
threadpool
方法说明
GetMaxThreads(out workerThreads, out completePortsThreads)线程池最大线程数,线程池异步IO最大线程数(默认我的60,30)GetMinThreads最小(默认我的4,4)SetMaxTheadsSetMinThreadsQueueUserWorkItem线程加入线程池,等待线程池调派执行
线程完成任务不会自行销毁,而是挂起状态回到线程池
向线程池发出请求时,挂起线程会再次激活
线程池线程默认为后台线程
Loom
在Update中不断检查需要回调的Action进行加锁回调,回调序列作为静态数据保存,可任意添加开启一个线程然后在Loom.RunAsyn()中调用需要回到Unity主线程更新界面时调用QueueOnMainThread()即可。简单好用。
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System;
using System.Threading;
using System.Linq;
public class Loom : MonoBehaviour
{
public static int maxThreads = 8;
private static int numThreads;
private static Loom _current;
//private int _count;
public static Loom Current
{
get
{
Initialize();
return _current;
}
}
private void Awake()
{
_current = this;
initialized = true;
}
private static bool initialized;
public static void Initialize()
{
if (!initialized)
{
if (!Application.isPlaying)
return;
initialized = true;
var g = new GameObject("Loom");
_current = g.AddComponent<Loom>();
#if !ARTIST_BUILD
UnityEngine.Object.DontDestroyOnLoad(g);
#endif
}
}
public struct NoDelayedQueueItem
{
public Action<object> action;
public object param;
}
private List<NoDelayedQueueItem> _actions = new List<NoDelayedQueueItem>();
public struct DelayedQueueItem
{
public float time;
public Action<object> action;
public object param;
}
private List<DelayedQueueItem> _delayed = new List<DelayedQueueItem>();
private List<DelayedQueueItem> _currentDelayed = new List<DelayedQueueItem>();
public static void QueueOnMainThread(Action<object> taction, object tparam)
{
QueueOnMainThread(taction, tparam, 0f);
}
public static void QueueOnMainThread(Action<object> taction, object tparam, float time)
{
if (time != 0)
{
lock (Current._delayed)
{
Current._delayed.Add(new DelayedQueueItem { time = Time.time + time, action = taction, param = tparam });
}
}
else
{
lock (Current._actions)
{
Current._actions.Add(new NoDelayedQueueItem { action = taction, param = tparam });
}
}
}
public static Thread RunAsync(Action a)
{
Initialize();
while (numThreads >= maxThreads)
{
Thread.Sleep(100);
}
Interlocked.Increment(ref numThreads);
ThreadPool.QueueUserWorkItem(RunAction, a);
return null;
}
private static void RunAction(object action)
{
try
{
((Action)action)();
}
catch
{
}
finally
{
Interlocked.Decrement(ref numThreads);
}
}
private void OnDisable()
{
if (_current == this)
{
_current = null;
}
}
// Use this for initialization
private void Start()
{
}
private List<NoDelayedQueueItem> _currentActions = new List<NoDelayedQueueItem>();
// Update is called once per frame
private void Update()
{
if (_actions.Count > 0)
{
lock (_actions)
{
_currentActions.Clear();
_currentActions.AddRange(_actions);
_actions.Clear();
}
for (int i = 0; i < _currentActions.Count; i++)
{
_currentActions[i].action(_currentActions[i].param);
}
}
if (_delayed.Count > 0)
{
lock (_delayed)
{
_currentDelayed.Clear();
_currentDelayed.AddRange(_delayed.Where(d => d.time <= Time.time));
for (int i = 0; i < _currentDelayed.Count; i++)
{
_delayed.Remove(_currentDelayed[i]);
}
}
for (int i = 0; i < _currentDelayed.Count; i++)
{
_currentDelayed[i].action(_currentDelayed[i].param);
}
}
}
}
调用:
//创建线程
Loom.RunAsync(() => {
Thread thread = new Thread(Start1);
thread.Start();
});
//回调
Loom.QueueOnMainThread((param) =>
{
Debug.LogError("1");
}, null);