CLR线程、线程池、任务的这些事

简介: CLR线程 CLR使用的是Windows的线程处理能力,目前的CLR实现一个CLR线程对应于一个Windows线程 System.Threading.Thread       System.Threading.Thread t = new System.Threading.Thread(op =>       {           Console.WriteLine(op);       });       t.Start("demo");       t.Join();  CLR线程池 创建和销毁线程是一个昂贵的操作,要耗费大量时间、资源,对性能也有影响。

CLR线程

CLR使用的是Windows的线程处理能力,目前的CLR实现一个CLR线程对应于一个Windows线程

System.Threading.Thread

      System.Threading.Thread t = new System.Threading.Thread(op =>

      {

          Console.WriteLine(op);

      });

      t.Start("demo");

      t.Join();

 

CLR线程池

创建和销毁线程是一个昂贵的操作,要耗费大量时间、资源,对性能也有影响。为改善这个情况,CLR包含了代码来管理它的线程池。可将线程池想象成可由你的程序使用的一个线程集合,每个CLR一个线程池,这个线程池可由CLR控制的所有AppDomian共享。如果一个进程加载了多个CLR,每个CLR都有自己的线程池。

        System.Threading.ThreadPool.QueueUserWorkItem(op =>

        {

            Console.WriteLine(op);

        },

        "demo");

 

执行上下文

每个线程都关联一个执行上下文结构,包括:安全设置(Thread.Principal Windows身份)、宿主设置(System.Threading.HostExecutionContextManager)、逻辑调用上下文数据(System.Runtime.Remoting.Messaging.CallContextLogicSetDataLogicGetData)

默认情况下,CLR自动造成初始线程的执行上下文复制到任何辅助线程,如果需要控制上下文的复制问题,可使用System.Threading.ExecutionContext类,如:

     // Put some data into the Main thread’s logical call context

        CallContext.LogicalSetData("Name""Jeffrey");

 

        // Initiate some work to be done by a thread pool thread

        // The thread pool thread can access the logical call context data 

        ThreadPool.QueueUserWorkItem(

           state => Console.WriteLine("Name={0}"CallContext.LogicalGetData("Name")));

 

 

        // Suppress the flowing of the Main thread’s execution context

        ExecutionContext.SuppressFlow();

 

        // Initiate some work to be done by a thread pool thread

        // The thread pool thread can NOT access the logical call context data

        ThreadPool.QueueUserWorkItem(

           state => Console.WriteLine("Name={0}"CallContext.LogicalGetData("Name")));

 

        // Restore the flowing of the Main thread’s execution context in case 

        // it employs more thread pool threads in the future

        ExecutionContext.RestoreFlow();

 

协作式取消

.net提供了标准的取消操作模式

   private static void CancellingAWorkItem() {

        CancellationTokenSource cts = new CancellationTokenSource();

        // Pass the CancellationToken and the number-to-count-to into the operation

        ThreadPool.QueueUserWorkItem(o => Count(cts.Token, 1000));

 

        Console.WriteLine("Press <Enter> to cancel the operation.");

        Console.ReadLine();

        cts.Cancel();  // If Count returned already, Cancel has no effect on it

        // Cancel returns immediately, and the method continues running here...

 

        Console.ReadLine();  // For testing purposes

    }

    private static void Count(CancellationToken token, Int32 countTo) {

        for (Int32 count = 0; count < countTo; count++) {

            if (token.IsCancellationRequested) {

                Console.WriteLine("Count is cancelled");

                break// Exit the loop to stop the operation

            }

 

            Console.WriteLine(count);

            Thread.Sleep(200);   // For demo, waste some time

        }

        Console.WriteLine("Count is done");

    }

任务

ThreadPool.QueueUserWorkItem虽然简单,担忧如下限制:

Ø  没有内建的机制知道操作什么时候完成

Ø  没有内建的机制在操作完成时获得一个返回值

System.Threading.Tasks下的类型可解决这个问题

      Task<Int32> t = new Task<Int32>(n => Sum((Int32)n), 10000);

 

        // You can start the task sometime later

        t.Start();

 

        // Optionally, you can explicitly wait for the task to complete

        t.Wait(); // FYI: Overloads exist accepting a timeout/CancellationToken

 

        // Get the result (the Result property internally calls Wait) 

        Console.WriteLine("The sum is: " + t.Result);   // An Int32 value

 

任务的取消使用“协作式取消”方式,CancellationTokenSource

 

一个任务完成时自动启动另一个新任务

Task.ContinueWith

 

任务可以启动子任务

 

任务工厂

         有时,可能需要创建一组Task对象来共享相同的状态,为了避免机械的将相同的参数传给每个Task的构造器,可以创建一个任务工厂来封装通用的状态。

 

 

参考

Clr Via C# 25 26

http://transbot.blog.163.com

http://ys-f.ys168.com/?CLR_via_CSharp_3rd_Edition_Code_by_Jeffrey_Richter.zip_55bism1e0e7bkisjthit2bso0cm5bs4bs1b5bktnql0c0bu22f05f12z

相关文章
|
21天前
|
监控 Kubernetes Java
阿里面试:5000qps访问一个500ms的接口,如何设计线程池的核心线程数、最大线程数? 需要多少台机器?
本文由40岁老架构师尼恩撰写,针对一线互联网企业的高频面试题“如何确定系统的最佳线程数”进行系统化梳理。文章详细介绍了线程池设计的三个核心步骤:理论预估、压测验证和监控调整,并结合实际案例(5000qps、500ms响应时间、4核8G机器)给出具体参数设置建议。此外,还提供了《尼恩Java面试宝典PDF》等资源,帮助读者提升技术能力,顺利通过大厂面试。关注【技术自由圈】公众号,回复“领电子书”获取更多学习资料。
|
1月前
|
监控 Java
java异步判断线程池所有任务是否执行完
通过上述步骤,您可以在Java中实现异步判断线程池所有任务是否执行完毕。这种方法使用了 `CompletionService`来监控任务的完成情况,并通过一个独立线程异步检查所有任务的执行状态。这种设计不仅简洁高效,还能确保在大量任务处理时程序的稳定性和可维护性。希望本文能为您的开发工作提供实用的指导和帮助。
95 17
|
3月前
|
存储 Java 数据库
如何处理线程池关闭时未完成的任务?
总之,处理线程池关闭时未完成的任务需要综合考虑多种因素,并根据实际情况选择合适的处理方式。通过合理的处理,可以最大程度地减少任务丢失和数据不一致等问题,确保系统的稳定运行和业务的顺利开展。
164 64
|
3月前
|
消息中间件 监控 Java
线程池关闭时未完成的任务如何保证数据的一致性?
保证线程池关闭时未完成任务的数据一致性需要综合运用多种方法和机制。通过备份与恢复、事务管理、任务状态记录与恢复、数据同步与协调、错误处理与补偿、监控与预警等手段的结合,以及结合具体业务场景进行分析和制定策略,能够最大程度地确保数据的一致性,保障系统的稳定运行和业务的顺利开展。同时,不断地优化和改进这些方法和机制,也是提高系统性能和可靠性的重要途径。
138 62
|
3月前
|
Prometheus 监控 Cloud Native
JAVA线程池监控以及动态调整线程池
【10月更文挑战第22天】在 Java 中,线程池的监控和动态调整是非常重要的,它可以帮助我们更好地管理系统资源,提高应用的性能和稳定性。
248 64
|
3月前
|
缓存 监控 Java
Java线程池提交任务流程底层源码与源码解析
【11月更文挑战第30天】嘿,各位技术爱好者们,今天咱们来聊聊Java线程池提交任务的底层源码与源码解析。作为一个资深的Java开发者,我相信你一定对线程池并不陌生。线程池作为并发编程中的一大利器,其重要性不言而喻。今天,我将以对话的方式,带你一步步深入线程池的奥秘,从概述到功能点,再到背景和业务点,最后到底层原理和示例,让你对线程池有一个全新的认识。
72 12
|
3月前
|
监控 安全 Java
在 Java 中使用线程池监控以及动态调整线程池时需要注意什么?
【10月更文挑战第22天】在进行线程池的监控和动态调整时,要综合考虑多方面的因素,谨慎操作,以确保线程池能够高效、稳定地运行,满足业务的需求。
133 38
|
3月前
|
Java
.如何根据 CPU 核心数设计线程池线程数量
IO 密集型:核心数*2 计算密集型: 核心数+1 为什么加 1?即使当计算密集型的线程偶尔由于缺失故障或者其他原因而暂停时,这个额外的线程也能确保 CPU 的时钟周期不会被浪费。
122 4
|
3月前
|
Java
线程池内部机制:线程的保活与回收策略
【10月更文挑战第24天】 线程池是现代并发编程中管理线程资源的一种高效机制。它不仅能够复用线程,减少创建和销毁线程的开销,还能有效控制并发线程的数量,提高系统资源的利用率。本文将深入探讨线程池中线程的保活和回收机制,帮助你更好地理解和使用线程池。
152 2
|
3月前
|
Prometheus 监控 Cloud Native
在 Java 中,如何使用线程池监控以及动态调整线程池?
【10月更文挑战第22天】线程池的监控和动态调整是一项重要的任务,需要我们结合具体的应用场景和需求,选择合适的方法和策略,以确保线程池始终处于最优状态,提高系统的性能和稳定性。
540 2