1、如何在Asp.Net Core中激活Session功能 首先添加Session包,其次在ConfigService方法中添加Session,然後在ConfigService中調用useSession。 2、什麼是中間件 指註入到應用中處理請求和響應的組件,是通過多個嵌套形成的 3、Applica ...
一臺伺服器能運行多少個線程,大致取決於CPU的管理能力。CPU負責線程的創建、協調、切換、銷毀、暫停、喚醒、運行等。
一個應用程式中,必須有一個進程,一個進程可同時多個線程協作處理。
同步:單線程,每一步都執行結束並返回結果,下一步處於等待,阻塞程式流
非同步:多線程,不需要等待執行結束,可繼續執行下一步,形成並行處理,無序的不可預測的執行順序
前臺線程:主線程退出後,子線程直至完成計算。
後臺線程:主線程退出後,子線程也會停止退出。
線程的應用
常用的線程創建方式
- new Thread
- ThreadPool.QueueUserWorkItem 後臺線程
- delegate 委托 invoke
- Task.Run / Task.Factory.StartNewd
- Parallel
- await / async
ThreadPool 線程池
每個進程都有一個線程池,每個線程池依環境因素分配不同的線程數
由線程池統一管理每個線程的創建/分配/銷毀。
// 設置可同時並行運行的線程數
ThreadPool.SetMinThreads
ThreadPool.SetMaxThreads
// 用線程池中的後臺線程執行方法
ThreadPool.QueueUserWorkItem(方法1);
Task
Task所用到的線程同樣來自於ThreadPool。
Action<object> action = (object obj) =>
{
Console.WriteLine("Task={0}, obj={1}, Thread={2}",
Task.CurrentId, obj,
Thread.CurrentThread.ManagedThreadId);
};
// Create a task but do not start it.
Task t1 = new Task(action, "alpha");
// Construct a started task
Task t2 = Task.Factory.StartNew(action, "beta");
// Block the main thread to demonstrate that t2 is executing
t2.Wait();
// Launch t1
t1.Start();
Console.WriteLine("t1 has been launched. (Main Thread={0})",
Thread.CurrentThread.ManagedThreadId);
// Wait for the task to finish.
t1.Wait();
// Construct a started task using Task.Run.
String taskData = "delta";
Task t3 = Task.Run( () => {
Console.WriteLine("Task={0}, obj={1}, Thread={2}",
Task.CurrentId, taskData,
Thread.CurrentThread.ManagedThreadId);
});
// Wait for the task to finish.
t3.Wait();
// Construct an unstarted task
Task t4 = new Task(action, "gamma");
// Run it synchronously
t4.RunSynchronously();
// Although the task was run synchronously, it is a good practice
// to wait for it in the event exceptions were thrown by the task.
t4.Wait();
// Task 的返回值(等待返回結果)
Task<int> task = new Task<int>(() =>
{
//...
return 0;
});
task.Start();
int result = task.Result;
// 僅僅啟動一個Task
Task.Run(() =>
{
//...
});
// 批量啟動 Task
// 同時並行運行至少30個線程的方式
ThreadPool.SetMinThreads(30, 50);
ThreadPool.SetMaxThreads(50, 70);
for (int i = 0; i < 30; i++)
{
Task.Run(() =>
{
//...
});
}
Parallel
多線程並行處理的 Parallel.Invoke,Parallel.For,Parallel.ForEach;無法確保順序處理。
// 示例:並行運行幾個方法
Parallel.Invoke(方法1, 方法2, () => 方法3, () => 方法4)
// ParallelOptions 參數設定
// 先指定啟用30個線程同時處理的設置
ParallelOptions paroptions = new ParallelOptions();
paroptions.MaxDegreeOfParallelism = 30;
// 指定數量的線程,並行執行200遍
List<int> datas = new List<int>();
Parallel.For(0, 200, paroptions, index =>
{
datas.add(index);
});
// 指定數量的線程,並行讀取數據
Parallel.ForEach(datas, paroptions, (item) =>
{
Console.WriteLine(item);
});
await / async
創建後臺進程並行處理,並取得處理結果。
// 執行 async 方法(後臺線程執行)
Task<string> _task_result_1 = t1.Func1();
// 主線程不等返回結果,繼續往下執行
// 執行方法
string _result_2 = t1.Func2();
// 以上兩個方法並行執行
// 取 Func1 的運行結果
string _result_1 = await _task_result_1;
// 整合兩個方法的運行結果
int _total_ = _result_1.length + _result_2.length;
常用的線程鎖
lock
封裝自應用級鎖Monitor類,需要有線程共用的鎖標識,告知其它線程是否等待。
Monitor
程式級鎖,於單個應用範圍內
// 給要操作的對象加把鎖,排他鎖
Monitor.Enter(T);
// 釋放當前鎖,允許其它線程使用了
Monitor.Exit(T);
Semaphore
限制可同時訪問某一資源或資源池的線程數,允許同時共用的線程數
// 創建時,定義同時的預設線程數和最多線程數(起始線程數,最多線程數)
Semaphore sem = new Semaphore(10, 20);
// 上鎖
sem.WaitOne();
// 釋放鎖(一次釋放線程數)
sem.Release(3);
Mutex
系統級鎖,內核對象,所以可跨進程跨應用// 阻擋鎖住當前塊,其它線程處於等待
// 超時後返回false,不允許其它線程進入
Mutex.WaitOne(timeout);
// 釋放當前,一個,允許其它線程進入
Mutex.ReleaseMutex();
線程安全
線程安全的類,通過 lock(xxx.SyncRoot) 實現線程同步,如:Array,ArrayList
線程安全的高性能集合類
ConcurrentBag 無序集合
ConcurrentStack 後進先出
ConcurrentQueue 先進先出
ConcurrentDictionary 鍵值對字典
個人拙見,有不妥望指出,萬分感謝。