多线程3——Parallel、线程取消、线程安全
1.Parallel
// Parallel Task.Run(() => { ParallelOptions parallelOptions = new ParallelOptions(); parallelOptions.MaxDegreeOfParallelism = 5;//控制执行的线程数量 Parallel.For(0, 50, parallelOptions,( i) =>//输出1~50 { Console.WriteLine($"开始{i+1}"); Thread.Sleep(500); Console.WriteLine($"结束{i+1}"); }); });
2.线程取消
try { //线程取消 List<Task> tasks = new List<Task>(); CancellationTokenSource cancellationToken = new CancellationTokenSource(); for (int i = 0; i < 50; i++) { int m = i;//临时变量“闭包” tasks.Add(Task.Run(() => { Console.WriteLine($"开始{m + 1}"); if (m == 10) cancellationToken.Cancel(); Thread.Sleep(1000); if(!cancellationToken.IsCancellationRequested) Console.WriteLine($"结束{m + 1}"); }, cancellationToken.Token)); } Task.WaitAll(tasks.ToArray()); } catch (Exception ex) { Console.WriteLine(ex.ToString()); }
3.线程安全
a.Interlocked
方法 | 作用 |
CompareExchange() | 安全比较两个值是不是相等。如果相等,将第三个值于其中一个值交换 |
Decrement() | 安全递减1,相当于 i-- |
Exchange() | 安全交换数据,相当于 a = 30 |
Increment() | 安全递加1,相当于 i++ |
Add() | 安全相加一个数值,相当于 a = a + 3 |
Read() | 安全读取数值,相等于int a=b |
b.引用System.Collections.Concurrent命名空间
ConcurrentXXX :这些集合是线程安全的,如果某个动作不适用于线程的当前状态,它们就返回false。在继续之前,总是霈要确认添加或提取元素是否成功。不能相信集合会完成任务。
ConcurrentQueue<T> 队列、ConcurrentStack<T> 堆栈、ConcurrentBag<T> 包、ConcurrentDictionary<TKey, TValue> 字典、BlockingCollection<T> 集合、BlockingCollection<T> 阻塞式集合