網站首頁 編程語言 正文
一、使用線程的理由
1、可以使用線程將代碼同其他代碼隔離,提高應用程序的可靠性。
2、可以使用線程來簡化編碼。
3、可以使用線程來實現并發執行。
二、基本知識
1、進程與線程:進程作為操作系統執行程序的基本單位,擁有應用程序的資源,進程包含線程,進程的資源被線程共享,線程不擁有資源。
2、前臺線程和后臺線程:通過Thread類新建線程默認為前臺線程。當所有前臺線程關閉時,所有的后臺線程也會被直接終止,不會拋出異常。
3、掛起(Suspend)和喚醒(Resume):由于線程的執行順序和程序的執行情況不可預知,所以使用掛起和喚醒容易發生死鎖的情況,在實際應用中應該盡量少用。
4、阻塞線程:Join,阻塞調用線程,直到該線程終止。
5、終止線程:Abort:拋出 ThreadAbortException 異常讓線程終止,終止后的線程不可喚醒。Interrupt:拋出 ThreadInterruptException 異常讓線程終止,通過捕獲異常可以繼續執行。
6、線程優先級:Highest AboveNormal Normal BelowNormal Lowest ,默認為Normal。
三、線程的使用
線程函數通過委托傳遞,可以不帶參數,也可以帶參數(只能有一個參數),可以用一個類或結構體封裝參數。
案例:
class Program
{
static void Main(string[] args)
{
Thread t1 = new Thread(new ThreadStart(TestMethod));//創建無參數數線程
Thread t2 = new Thread(new ParameterizedThreadStart(TestMethod));//創建帶參數的線程
//設置為后臺進程
t1.IsBackground = true;
t2.IsBackground = true;
t1.Start();
t2.Start("hello");
Console.ReadKey();
}
public static void TestMethod()
{
Console.WriteLine("不帶參數的線程函數");
}
//參數要定義為object 類型
public static void TestMethod(object data)
{
string datastr = data as string;
Console.WriteLine("帶參數的線程函數,參數為:{0}", datastr);
}
}
四、線程池
由于線程的創建和銷毀需要耗費一定的開銷,過多的使用線程會造成內存資源的浪費,出于對性能的考慮,于是引入了線程池的概念。線程池維護一個請求隊列,線程池的代碼從隊列提取任務,然后委派給線程池的一個線程執行,線程執行完不會被立即銷毀,這樣既可以在后臺執行任務,又可以減少線程創建和銷毀所帶來的開銷。
線程池線程默認為后臺線程(IsBackground)。
class Program
{
static void Main(string[] args)
{
//將工作項加入到線程池隊列中,這里可以傳遞一個線程參數
ThreadPool.QueueUserWorkItem(TestMethod, "Hello");
Console.ReadKey();
}
//線程函數
public static void TestMethod(object data)
{
string datastr = data as string;
Console.WriteLine(datastr);
}
}
五、Task類
使用ThreadPool的QueueUserWorkItem()方法發起一次異步的線程執行很簡單,但是該方法最大的問題是沒有一個內建的機制讓你知道操作什么時候完成,有沒有一個內建的機制在操作完成后獲得一個返回值。為此,可以使用System.Threading.Tasks中的Task類。
構造一個Task<TResult>對象,并為泛型TResult參數傳遞一個操作的返回類型。
class Program
{
static void Main(string[] args)
{
Task<Int32> t = new Task<Int32>(n => Sum((Int32)n), 1000);
t.Start();
t.Wait();
Console.WriteLine(t.Result);
Console.ReadKey();
}
private static Int32 Sum(Int32 n)
{
Int32 sum = 0;
for (; n > 0; --n)
checked{ sum += n;} //結果太大,拋出異常
return sum;
}
}
一個任務完成時,自動啟動一個新任務。
一個任務完成后,它可以啟動另一個任務,下面重寫了前面的代碼,不阻塞任何線程。
class Program
{
static void Main(string[] args)
{
Task<Int32> t = new Task<Int32>(n => Sum((Int32)n), 1000);
t.Start();
//t.Wait();
Task cwt = t.ContinueWith(task => Console.WriteLine("The result is {0}", t.Result));
Console.ReadKey();
}
private static Int32 Sum(Int32 n)
{
Int32 sum = 0;
for (; n > 0; --n)
checked { sum += n; } //結果溢出,拋出異常
return sum;
}
}
六、委托異步執行
委托的異步調用:BeginInvoke() 和 EndInvoke()
namespace Test
{
public delegate string MyDelegate(object data);
class Program
{
static void Main(string[] args)
{
MyDelegate mydelegate = new MyDelegate(TestMethod);
IAsyncResult result = mydelegate.BeginInvoke("Thread Param", TestCallback, "Callback Param");
//異步執行完成
string resultstr = mydelegate.EndInvoke(result);
}
//線程函數
public static string TestMethod(object data)
{
string datastr = data as string;
Console.WriteLine(datastr);
return datastr;
}
//異步回調函數
public static void TestCallback(IAsyncResult data)
{
Console.WriteLine(data.AsyncState);
}
}
}
異步回調函數在上面線程函數執行結束后,將要退出時執行。
原文鏈接:https://www.cnblogs.com/wml-it/p/14808683.html
相關推薦
- 2022-10-15 使用Pycharm創建一個Django項目的超詳細圖文教程_python
- 2022-10-21 PID原理與python的簡單實現和調參_python
- 2024-03-20 版本沖突error in ./src/styles/element-variables.scss:N
- 2022-11-13 kvm?透傳顯卡至win10虛擬機的方法_Kvm
- 2022-07-29 Golang的鎖機制與使用技巧小結_Golang
- 2022-07-25 .Net行為型設計模式之訪問者模式(Visitor)_基礎應用
- 2022-09-23 C#實現目錄跳轉(TreeView和SplitContainer)的示例代碼_C#教程
- 2022-09-11 Shell之免交互的實現_linux shell
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支