zoukankan      html  css  js  c++  java
  • .NET多线程知识快速学习

    多线程是一个不会过时的话题,因为每个开发的成长必然要掌握这个知识点,否则半懂不懂怎么保证系统的可靠性和性能,其实在网上随便一搜都会有海量的文章说这个话题,大多数写得很细写得非常好,但发现很少有概览性的文章,我希望能借本文给大家一个全局视野,结合多年实践帮大家快速学习或者回顾思考,对感兴趣的知识点再深入学习了解。

    一、知识点概括

    二、具体实例演示如何实现

    > Thread 多线程最基础的类

    //ThreadPool.GetMaxThreads(out int maxTCount, out int maxPCount);
    //ThreadPool.GetMinThreads(out int minTCount, out int minPCount);
    //ThreadPool.SetMaxThreads(maxTCount, maxPCount);// 调整最大线程数
    //ThreadPool.SetMinThreads(minTCount, minPCount);// 调整最小线程数
    
    long tick = C_ITEM_COUNT;
    ManualResetEvent signal = new ManualResetEvent(false);
    Console.WriteLine("========== 示例:采用Thread执行处理 ==========");
    for (int i = 0; i < C_ITEM_COUNT; i++)
    {
        new Thread((obj) =>
        {
            Thread.Sleep(500);
            Console.Write(" {0} ", obj);
            if (Interlocked.Decrement(ref tick) == 0)
                signal.Set();
        }).Start(i);
    }
    Console.Write(" 等待子线程执行 ");
    signal.WaitOne();
    Console.WriteLine();
    Console.WriteLine("全部线程执行完毕,按任意键继续...");

    > ThreadPool 线程池,XX池的概念可以广泛应用于其他资源管理,例如字体池(防句柄泄露)、短信猫池等等

    tick = C_ITEM_COUNT;
    signal.Reset();
    Console.WriteLine();
    Console.WriteLine("========== 示例:采用ThreadPool执行处理 ==========");
    for (int i = 0; i < C_ITEM_COUNT; i++)
    {
        ThreadPool.QueueUserWorkItem((obj) =>
        {
            Thread.Sleep(500);
            Console.Write(" {0} ", obj);
            if (Interlocked.Decrement(ref tick) == 0)
                signal.Set();
        }, i);
    }
    Console.Write(" 等待子线程执行 ");
    signal.WaitOne();
    Console.WriteLine();
    Console.WriteLine("全部线程执行完毕,按任意键继续...");

    > Task 任务,功能丰富用法灵活。结合现实生活用字面意思去理解就好:可以同时做多个任务,任务做完可以接着做其他任务,任务可能会取消等等。

    tick = C_ITEM_COUNT;
    signal.Reset();
    Console.WriteLine();
    Console.WriteLine("========== 示例:采用Task执行处理,注意取消了处理{0}的进程 ==========", C_ITEM_COUNT - 2);
    var tasks = new Tuple<Task, CancellationTokenSource>[C_ITEM_COUNT];
    for (int i = 0; i < C_ITEM_COUNT; i++)
    {
        var cts = new CancellationTokenSource();
        var task = Task.Factory.StartNew((obj) =>
        {
            Thread.Sleep(500);
            Console.Write(" {0} ", obj);
        }, i, cts.Token);
        task.ContinueWith((t) =>
        {
            if (Interlocked.Decrement(ref tick) == 0)
                signal.Set();
        });
        tasks[i] = new Tuple<Task, CancellationTokenSource>(task, cts);
    }
    
    tasks[C_ITEM_COUNT - 2].Item2.Cancel();// 取消线程。
    
    Console.Write(" 等待子线程执行 ");
    signal.WaitOne();
    Console.WriteLine();
    Console.WriteLine("全部线程执行完毕,按任意键继续...");

    > Parallel 并行

    tick = C_ITEM_COUNT;
    signal.Reset();
    Console.WriteLine();
    Console.WriteLine("========== 示例:采用Parallel执行处理 ==========");
    Parallel.For(0, C_ITEM_COUNT, obj =>
    {
        Thread.Sleep(500);
        Console.Write(" {0} ", obj);
        if (Interlocked.Decrement(ref tick) == 0)
            signal.Set();
    });
    
    Console.Write(" 等待子线程执行 ");
    signal.WaitOne();
    Console.WriteLine();
    Console.WriteLine("全部线程执行完毕,按任意键继续...");

    以上示例执行结果如下,重点可以关注下"等待子线程执行"这个节点,理解主线程和各子线程的优先执行顺序

    三、性能对比(理解线程池技术的性能也可以通过最大最小线程数调节)

    > 循环数:200,线程池参数:默认

    > 循环数:200,线程池参数:50 - 1000

    > 循环数200,线程池参数:100-1000

     

    > 循环数200,线程池参数:200-1000

     

    最大线程数 ~ 最小线程数 Thread(ms) ThreadPool(ms) Task(ms) Parallel(ms)
    2047/1000 ~ 12/12 2712.09 8057.14 8585.01 7526.57
    1000/1000 ~ 50/50 2733.25 2289.96 2218.29 3660.33
    1000/1000 ~ 100/100 2503.08 1620.73 1534.50 1742.78
    1000/1000 ~ 200/200 2999.27 1436.24 1150.21 935.22

     四、结论

    > Thread就像脱缰的野马,不受控制,创建多少就运行多少,可能少量时效率是高了,量大的时候除了性能没优势,还可能导致句柄泄露。

    > ThreadPool与Task类似,但Task相比效率更高用法更灵活。

    > Parallel自带了同步功能,不需要用信号量来做额外的同步等待。

    > ThreadPool、Task、Parallel的性能都取决于线程池最大线程数和最小线程数。

    > 推荐使用 Task 和 Parallel,具体用哪个可以参考用法自己斟酌。

  • 相关阅读:
    聚类算法学习-kmeans,kmedoids,GMM
    hdu
    高仿精仿微信应用ios源码下载
    UVA 116 Unidirectional TSP 经典dp题
    [置顶] 动态规划之切割钢条
    poj
    求解printf函数?
    实现多文件上传在iOS开发中
    开源DirectShow分析器和解码器: LAV Filter
    <Win32_20>纯c语言版的打飞机游戏出炉了^_^
  • 原文地址:https://www.cnblogs.com/yokeqi/p/11885819.html
Copyright © 2011-2022 走看看