[多线程] Thread
?
多線程
概述
單任務處理:一個任務完成后才能進行下一個任務。
多任務處理:CPU分時操作,每個任務看似同時運行。
進程
應用程序的一個運行實例,包含程序所需資源的內存區域,是操作系統進行資源分配的單元,進程隔離了正在執行的不同程序。(打開某一個軟件,分配CPU,隔離其他軟件)
優點:進程間相互獨立,互不影響。
線程
進程中的一個執行單元(進程是程序邊界,要靠線程執行程序,線程指向方法,執行完畢釋放線程),是CPU分配時間片的單位,一個進程可以包含多個線程,且相互獨立,共享當前進程所有資源。
優點:
缺點:
注意事項:
多線程
在單核系統的一個單位時間內,CPU只能運行單個線程,運行順序取決于線程的優先級。如果在單位時間內線程未能完成執行,系統就會把線程的狀態信息保存到線程的本地存儲器(TLS) 中,以便下次執行時恢復執行。因為切換頻密,所以多線程可被視作同時運行,而實際只是一個假象。
在多核系統的一個單位時間內,進程或線程可以在不同的CPU中運行,使得真正的并行處理。
適用性
耗時的任務,通過多線程可以并行處理。
一個程序完成多個任務,通過多個線程使用多核CPU來處理,可以提升性能。
多線程實現
命名空間:System.Threading;
using System.Collections; using System.Collections.Generic; using UnityEngine; using System.Threading;public class ThreadDemo1 : MonoBehaviour {private Thread thread;private void Start01(){//Func1();//同步調用 一次性完成0 1 2 3 4 ....//線程調用//thread = new Thread(Fun1);//thread.Start();//睡眠一秒 期間沒有CPU調度 0 睡眠一秒,依次循環 1 2 3 4... //thread = new Thread(Fun2);//thread.Start(5);//方法重載 參數object類型 thread = new Thread(Fun4);thread.Start();//ThreadPool.QueueUserWorkItem(Fun3,null);//線程池開辟的線程無法設置前后臺/優先級等//通過線程池開辟線程 不能Start啟用 }//thread.Start() //無參private void Fun1(){for (int i = 0; i < 30; i++){signal.WaitOne(3000);//整數 代表最長的等待時間Thread.Sleep(1000);print(i);}}////thread.Start(5) //有參private void Fun2(object o){int count = (int)o;for (int i = 0; i < count; i++){Thread.Sleep(1000);print(i);}}/// <summary>/// 對象池/// </summary>private void Fun3(object o){//int[] arr = (int[])o;//int count = (int)o;for (int i = 0; i < 5; i++){Thread.Sleep(1000);//模擬此時操作一分鐘print(i);//主線程 卡 指的就是生命周期 }}/// <summary>/// 死循環 怎么辦/// </summary>private void Fun4(){int n = 0;while (true){Thread.Sleep(1000);print(++n);}}/// <summary>/// 退出線程/// </summary>private void OnApplicationQuit(){//thread.Abort();//結束線程//主線程卡頓的情況 可以開辟新的線程 }/// <summary>/// 信號燈/// </summary>private ManualResetEvent signal;private void Start(){//信號燈 綠燈行 紅燈停signal = new ManualResetEvent(true);//true表示綠燈 false 表示紅燈thread = new Thread(Fun1);thread.Start();}private void OnGUI(){if (GUILayout.Button("線程暫停")){signal.Reset();}if (GUILayout.Button("線程繼續")){signal.Set();}} } View CodeThread?
?????????????Thread thread = new Thread(工作方法);
?????????????thread.Start();
?????????????thread.?Abort?();
ThreadPool
在頻繁創建和銷毀線程時使用線程池技術,可以有效減少時間以及系統資源的開銷。
ThreadPool.QueueUserWorkItem(工作方法);
?
前/后臺線程
?
前臺線程:程序必須等待所有前臺線程結束后才能退出。(只要有一個前臺線程未退出,進程就不會終止!即說的就是程序不會關閉!)[Thread創建的線程默認前臺線程]
?
后臺線程:程序不考慮后臺線程,后臺線程隨程序退出而結束。[ThreadPool創建的線程默認后臺線程]
?
備注:Unity程序退出后,前臺線程也隨即關閉。
?
新建的子線程可以是前臺線程或者后臺線程,前臺線程必須全部執行完,即使主線程關閉掉,這時進程仍然存活。
?
線程狀態
未啟動狀態?Unstarted:創建線程對象。
運行狀態Running:執行綁定的方法。
等待睡眠阻塞狀態?WaitSleepJoin:暫時停止執行,資源交給其他線程使用。
終止狀態?Stopped:線程銷毀。
?
using System.Collections; using System.Collections.Generic; using UnityEngine; using System; using UnityEngine.UI; using System.Threading;public class ThreadDemo : MonoBehaviour {private int second = 60;private Text text;private void Start(){text = GetComponent<Text>();Thread thread = new Thread(Timer);thread.Start();}private void Update(){if (action!=null){action();action = null;}}private void Timer(){while (second>0){Thread.Sleep(1000);//睡一會 期間沒有CPU的調度 action = () =>{second--;text.text = string.Format("{0:d2}:{1:d2}", second / 60, second % 60);};} }private Action action; }線程同步
需要同步的原因:?
多個線程同一時刻訪問共享資源(線程共享實例變量,靜態變量),由于每個線程都不知道其他線程的操作,結果將產生不可預知的數據損壞。?
?
同步:
線程之間相互等待排隊執行。
?
如何同步:
將需要同步的代碼用關鍵字lock鎖定,鎖定后該代碼對于線程來講就是獨占使用的。當其他線程試圖進入被鎖定的臨界區時,只能等待解鎖后才可訪問。因此鎖定代碼時是排隊訪問的,所以叫線程同步。?
?
Lock鎖原理:
對象在堆中的分配:實例成員、同步塊索引 (默認索引-1)、類型指針(指向類型對象)。 ?????
對象上鎖后,同步索引塊會指向同步塊數組中的一個對象。
當其他對象執行lock的時候會等待該對象同步索引設置為-1。
?
using System.Collections; using System.Collections.Generic; using UnityEngine; using System.Threading;public class Bank {public static int Money = 1;public static object o = new object();//必須使用引用類型//優先使用objectpublic static void Get(int val){lock (o)//-1 0 只有是-1的時候 鎖打開 否則鎖關閉{ //同步塊索引 類型對象指針//共享讀 獨占寫//枷鎖(對象) 流程if (Money >= val){//線程沖突 0 -1 -2 如何解決???加鎖Thread.Sleep(1000);Money -= val;Debug.Log("取錢成功!余額:" + Money);}else{Debug.Log("取錢失敗!余額:" + Money);}//線程離開代碼塊 索引塊 設置為-1 }} }public class ThreadDemo2 : MonoBehaviour {private void Start(){//Bank.Get(1); //同步調用 排隊ThreadPool.QueueUserWorkItem(o =>{Bank.Get(1);});////線程調用(多線程) 不排隊 } }?
轉載于:https://www.cnblogs.com/ASsss/p/10438885.html
總結
以上是生活随笔為你收集整理的[多线程] Thread的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Java实现 栈 和 队列
- 下一篇: Web框架与HTTP协议