簡(jiǎn)介
自己開始接觸一下多線程
Thread
- 屬性:主線程id為1,優(yōu)先級(jí)Lowest其徙,IsThreadPoolThread為false,IsBackground為false
- 一個(gè)線程默認(rèn)占用1M的堆椗缁В空間唾那,也可以修改
屬性 | 說明 |
---|---|
CurrentThreadManagedThreadId | get 當(dāng)前線程 |
Name | get;set 線程名稱 |
IsBackground | get;set 是否為后臺(tái)線程 |
IsThreadPoolThread | get 是否屬于托管線程池 |
ManagedThreadId | get 當(dāng)前托管線程唯一標(biāo)識(shí)符 |
IsAlive | 當(dāng)前線程執(zhí)行狀態(tài) |
Priority | 當(dāng)前線程調(diào)度優(yōu)先級(jí) |
ThreadState | 當(dāng)前線程的狀態(tài)(運(yùn)行停止后臺(tái)禁止…) |
方法:
方法 | 說明 |
---|---|
Start | 開啟 |
Suspend | 掛起 |
Resume | 繼續(xù)掛起的線程 |
Abort | 終止 |
Sleep | 當(dāng)前線程掛起或阻塞指定時(shí)間 |
簡(jiǎn)單實(shí)例
-
創(chuàng)建開始,有參函數(shù)參數(shù)只能有一個(gè)褪尝,而且是object類型闹获,但是既然都是object了,就可以改變一下傳更多參數(shù)
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()); } //單個(gè)參數(shù) private void Start2(object log) { Debug.LogError("Start2:" + Thread.CurrentThread.ManagedThreadId.ToString()+log); } //多個(gè)參數(shù) 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; } }
輸出:每次運(yùn)行河哑,主線程id為1避诽,新線程的id都不同,會(huì)累加璃谨,輸出順序不固定
threadpool
方法 | 說明 |
---|---|
GetMaxThreads(out workerThreads, out completePortsThreads) | 線程池最大線程數(shù)沙庐,線程池異步IO最大線程數(shù)(默認(rèn)我的60,30) |
GetMinThreads | 最小(默認(rèn)我的4,4) |
SetMaxTheads | |
SetMinThreads | |
QueueUserWorkItem | 線程加入線程池佳吞,等待線程池調(diào)派執(zhí)行 |
線程完成任務(wù)不會(huì)自行銷毀拱雏,而是掛起狀態(tài)回到線程池
向線程池發(fā)出請(qǐng)求時(shí),掛起線程會(huì)再次激活
線程池線程默認(rèn)為后臺(tái)線程
Loom
- 在Update中不斷檢查需要回調(diào)的Action進(jìn)行加鎖回調(diào)底扳,回調(diào)序列作為靜態(tài)數(shù)據(jù)保存铸抑,可任意添加
- 開啟一個(gè)線程然后在Loom.RunAsyn()中調(diào)用需要回到Unity主線程更新界面時(shí)調(diào)用QueueOnMainThread()即可。簡(jiǎn)單好用衷模。
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);
}
}
}
}
調(diào)用:
//創(chuàng)建線程
Loom.RunAsync(() => {
Thread thread = new Thread(Start1);
thread.Start();
});
//回調(diào)
Loom.QueueOnMainThread((param) =>
{
Debug.LogError("1");
}, null);