老鐵
先不廢話,簡單粗暴,直接來原始碼:
using
System;
using
System。Collections。Concurrent;
using
System。Collections。Generic;
using
System。Threading;
using
System。Threading。Tasks;
using
System。Windows。Forms;
namespace
TestConsole
{
class
Program
{
private
static
ManualResetEvent manualResetEvent =
new
ManualResetEvent(
false
);
//AutoResetEvent略去
//private static List
private
static
ConcurrentBag<
int
> list =
new
ConcurrentBag<
int
>();
private
static
CancellationTokenSource cancellationToken =
new
CancellationTokenSource();
private
static
ConcurrentDictionary<
int
,
string
> concurrentDictionary =
new
ConcurrentDictionary<
int
,
string
>();
private
static
ConcurrentQueue<
int
> concurrentQueue =
new
ConcurrentQueue<
int
>();
static
void
Main
(
string
[] args
)
{
try
{
//ThreadSafetyTest();
//ManualResetEventHandler();
//DelegateTest();
TasKTest();
Console。ReadKey();
}
catch
(Exception ex)
{
MessageBox。Show(ex。StackTrace +
“ ”
+ ex。Message);
}
}
#
region
TASK用法舉例
static
void
TasKTest
(
)
{
//帶返回值的task
Task
async
() =>
{
await
Task。Delay(
5000
);
return
“老鐵666”
;
}, cancellationToken。Token);
//cancellationToken。Cancel();
while
(!mytask。Wait(
100
))
//在指定時間執行完成就返回true
{
Console。Write(
“。”
);
}
Console。WriteLine(mytask。Result);
//task任務取消,所以獲取task。Result會報錯
Task taskFactory = Task。Factory。StartNew(() =>
{
Thread。Sleep(
1000
);
Console。WriteLine(
“perfect!”
);
});
Console。WriteLine(taskFactory。Status);
taskFactory。Wait();
//taskFactory任務完成才往下執行
Task。WaitAll(mytask, taskFactory);
//所有任務完成再往下執行
Task。WaitAny(mytask, taskFactory);
//任一任務完成就往下執行
Console。WriteLine(taskFactory。Status);
Task taskTest = taskFactory。ContinueWith(DoOnSecond);
//ContinueWith用法舉例
}
static
void
DoOnSecond
(
Task t
)
{
Console。WriteLine(
“task {0} finished”
, t。Id);
Console。WriteLine(
“this task id {0}”
, Task。CurrentId);
Console。WriteLine(
“do some cleanup”
);
}
#
endregion
#
region
ManualResetEvent 用法舉例
private
static
void
ManualResetEventHandler
(
)
{
Thread t1 =
new
Thread(Thread1);
t1。Start();
Thread t2 =
new
Thread(Thread2);
t2。Start();
Thread。Sleep(
2000
);
manualResetEvent。Set();
Thread。Sleep(
5000
);
t1。Abort();
//放棄執行執行緒t1
Console。WriteLine(t1。ThreadState);
Console。WriteLine(t2。ThreadState);
}
static
void
Thread1
(
)
{
Console。WriteLine(manualResetEvent。WaitOne()。ToString());
//等待 manualResetEvent。Set()後執行
manualResetEvent。Reset();
// 將訊號置為初始狀態,即false
//Console。WriteLine(manualResetEvent。WaitOne()。ToString());//阻塞當前執行緒,讓他等待著
MessageBox。Show(
“Thread1 run end”
);
Parallel。For(
0
,
100000000
, item =>
{
Console。WriteLine(item。ToString());
});
}
static
void
Thread2
(
)
{
Console。WriteLine(manualResetEvent。WaitOne(
10000
)。ToString());
//10秒內收到 manualResetEvent。Set(),即true就往下執行,或者超過100秒,也往下執行,但是狀態依然為false
MessageBox。Show(
“Thread2 run end”
);
}
#
endregion
#
region
執行緒安全之ConcurrentBag 驗證
private
static
void
ThreadSafetyTest
(
)
{
int
count =
0
;
Task t =
new
Task(() =>
{
while
(
true
)
{
Thread。Sleep(
1000
);
count++;
list。Add(count);
}
});
t。Start();
Task。Run(() =>
{
while
(
true
)
{
foreach
(
var
item
in
list)
{
Thread。Sleep(
1000
);
Console。WriteLine(
$“
{list。Count}
”
);
}
}
});
}
#
endregion
public
static
void
DelegateTest
(
)
{
Func<
string
,
string
> RetBook =
new
Func<
string
,
string
>(FuncBook);
Console。WriteLine(RetBook(
“《平凡的世界》”
));
}
public
static
string
FuncBook
(
string
BookName
)
{
return
BookName;
}
}
}
上面程式碼邏輯要是全懂了,下面就可以跳過了,
沒看懂的繼續……。
① 首先,執行第一個方法
ThreadSafetyTest();
涉及知識點:
task的建立和使用;
foreach遍歷
執行緒安全集合ConcurrentBag用法
修改這裡後執行:
ThreadSafetyTest();
//ManualResetEventHandler();
//DelegateTest();
//TasKTest();
執行結果如下:
這個方法體的作用主要是開了兩個執行緒,第一個執行緒每隔1秒向集合新增一個數,第二個執行緒每隔一秒,便利輸出集合。在這裡集合要是改成list的,即:
private
static
ConcurrentBag<
int
>
list
=
new
ConcurrentBag<
int
>();
改成=>
private
static
List<
int
>
list
=
new
List<
int
>();
執行過程會報錯:
非執行緒安全,“集合已修改;可能無法執行列舉操作。”
原因解釋:不管是讀還是寫,同一時刻只能做一件事情,要麼讀,要麼寫,多個執行緒對同一個集合進行讀寫操作,就難免會出現執行緒安全問題,當然你可以
用lock關鍵字,進行執行緒同步,但是效能並不是特別理想,然後我嘗試使用SynchronizedList
知識拓展:執行緒安全的佇列和字典:
ConcurrentDictionary<
int
,
string
> concurrentDictionary =
new
ConcurrentDictionary<
int
,
string
>();
ConcurrentQueue<
int
> concurrentQueue =
new
ConcurrentQueue<
int
>();
② 接下來,執行第二個方法
ManualResetEventHandler();
涉及知識點:
ManualResetEvent用法(和AutoResetEvent類似,區別自己去學習);
主要包括:
manualResetEvent。Reset(); manualResetEvent。Set();
manualResetEvent。WaitOne()和manualResetEvent。WaitOne(time)
Thread執行緒建立和使用;
重點解釋:
Console。WriteLine(manualResetEvent。WaitOne(10000)。ToString());10秒內收到 manualResetEvent。Set(),即true就往下執行,或者超過100秒,也往下執行,
但是狀態依然為false
最後的執行結果:
③ 接下來,執行第三個方法
DelegateTest();
知識點:帶引數,帶返回值的委託
Func的用法
執行結果:
總結一下 :
無返回就用action,有返回就用Func
④ 最後,執行第四個方法
DelegateTest();
涉及知識點:
task的建立和使用前面已經提供了兩種建立方式,這裡又提供了新的方式Task。Factory。StartNew(() =>{});
取消task任務之CancellationTokenSource的用法;
task的執行緒管控方法Task。。Wait(time),Task。WaitAll(), Task。WaitAny(),task。ContinueWith。
執行結果:
原創不易,用100+行程式碼串接這麼多重要知識點更加不易。
老鐵666
老鐵到底溜不溜,在看轉發走起來!
進技術交流群的,加小編微信zls20210502,切記備註:進群!
專案工程下載地址:
連結: https://pan。baidu。com/s/1MEm-CjQjrReP6jxyqpLjQA
提取碼: wr3n
技術群: 需要進技術群的新增小編微信mm1552923,備註:加群;