第四节:Task的启动的四种方式以及Task、TaskFactory的线程等待和线程延续的解决方案

一. 背景

揭秘:

  在前面的章节介绍过,Task出现之前,微软的多线程处理方式有:Thread→ThreadPool→委托的异步调用,虽然也可以基本业务需要的多线程场景,但它们在多个线程的等待处理方面、资源占用方面、线程延续和阻塞方面、线程的取消方面等都显得比较笨拙,在面对复杂的业务场景下,显得有点捉襟见肘了。

  正是在这种背景下,Task应运而生。

  Task是微软在.Net 4.0时代推出来的,也是微软极力推荐的一种多线程的处理方式,Task看起来像一个Thread,实际上,它是在ThreadPool的基础上进行的封装,Task的控制和扩展性很强,在线程的延续、阻塞、取消、超时等方面远胜于Thread和ThreadPool。

 

二. Task的4种启动方式

概要: 

  Task的启动有4种方式,其中3种异步启动开启一个新线程,1种同步启动的方式(有点和委托类似,BeginInvoke异步启动,Invoke同步启动),分别是:实例化的方式+Start方法启动、Task下Run方法启动、TaskFactory工厂的StartNew方法启动、Task下的同步方法RunSynchronously 启动。

1. 实例化的方式启动,调用Start方法

   Task的构造函数中的参数是Action委托(注:不是Action<>多个重载),所以直接使用 ()=>{   }的方式传参,简洁明了,然后调用Start方式启动。

2. 调用Task类下的静态方法Run,进行启动

   使用该方式启动,更加简洁,不需要实例化,也不需要调用Start方法,Run方法直接通过Action委托的方式进行传参即可(即:  ()=>{} )。

3. TaskFactory工厂启动

   使用TaskFactory工厂的StartNew方法启动,其中TaskFactory工厂可以直接实例化,或者 Task.Factory (推荐)。

 

4. 实例化方式RunSynchronously同步启动

   Task实例化的方式,然后调用同步方法RunSynchronously ,进行线程启动。(PS: 类似委托开启线程,BeginInvoke是异步,而Invoke是同步)

 

三. Task的线程等待和延续

揭秘:

  线程等待和延续通常情况放在一起来说,在同步方法中,即在单线程中,业务代码块按照从上往下的顺序执行,下面的代码块必须要等上面的代码块执行完毕后才能继续执行,这本身就是一种等待和延续,只不过是单线程内的等待和延续。

  同理,来到多线程领域,这里的等待就不单单局限于代码块之间的等待和延续了,而是上升到某个线程 要等待 另外一个线程执行完毕后方能执行,这里特别说明一下,前面的章节提到线程等待基本上都是主线程在等子线程,当然,完全可能是子线程之间的相互等待和延续(实际上,这种情况更多)。

  Task下的线程等待和延续主要以下几类:

  ①. Wait:针对单个Task的实例,可以task1.wait进行线程等待.  <Task的实例方法>

  ②. WaitAny:执行的线程等待其中任何一个线程执行完毕即可执行(如果主线程执行,则卡主线程)  <Task的静态方法>

  ③. WaitAll:执行的线程等待其中所有线程执行完毕方可执行(如果主线程执行,则卡主线程)       <Task的静态方法>

  ④. WhenAny:与下面ContinueWith配合执行,当传入的线程中任何一个线程执行完毕,继续执行ContinueWith中的任务(属于开启新线程,不卡主线程)   <Task的静态方法>

  ⑤. WhenAll:与下面ContinueWith配合执行,当传入的线程中所有线程执行完毕,继续执行ContinueWith中的任务(属于开启新线程,不卡主线程)     <Task的静态方法>

  ⑥. ContinueWith:和上面WhenAny和WhenAll配合使用    <Task的实例方法>

1. WaitAny(执行的线程等待其中任何一个线程执行完毕即可执行)

   这里给出线程等待加入集合中的代码,下面的线程等待通用这一部分代码,将不再列出。

2. WaitAll(执行的线程等待其中所有线程执行完毕方可执行)

 

3. WhenAny+ContinueWith

    当其中一个线程执行完成后,新开启了一个线程执行,继续执行新业务,所以执行过程中,不卡主线程。

4. WhenAll+ContinueWith

   当其中所有线程执行完成后,新开启了一个线程执行,继续执行新业务,所以执行过程中,不卡主线程。

四. TaskFactory的线程等待

说明: TaskFactory可以开启线程,当然也对应的线程的等待和延续。

  ①:ContinueWhenAny:等价于Task的WhenAny+ContinueWith

  ②:ContinueWhenAll:等价于Task的WhenAll+ContinueWith

1. ContinueWhenAny

 

2. ContinueWhenAll

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/438261.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java中对字符串的操作

字符串反转 StringBuffer 或 StringBuilder 的 reverse方法 String s1 new StringBuilder(str).reverse().toString(); String s3 new StringBuffer(str).reverse().toString(); System.out.println(s1);//cba System.out.println(s3);//cbaList集合拼接成逗号分隔的字符串…

第五节:Task构造函数之TaskCreationOptions枚举处理父子线程之间的关系。

一. 整体说明 揭秘&#xff1a; 通过F12查看Task类的源码(详见下面的截图)&#xff0c;发现Task类的构造函数有有一个参数为&#xff1a;TaskCreationOptions类型&#xff0c;本章节可以算作是一个扩展章节&#xff0c;主要就来研究TaskCreationOptions类的作用。 该类主要用来…

List,Map,实体类,字符串相互转换

添加依赖 <dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.2.7</version></dependency> List,实体类字符串想换转换 package Map;import com.alibaba.fastjson.*; import dto.Pers…

第六节:深入研究Task实例方法ContinueWith的参数TaskContinuationOptions

一. 整体说明 揭秘&#xff1a; 该章节的性质和上一个章节类似&#xff0c;也是一个扩展的章节&#xff0c;主要来研究Task类下的实例方法ContinueWith中的参数TaskContinuationOptions。 通过F12查看TaskContinuationOptions的源码&#xff0c;知道主要有这么几个参数&#xf…

java8 stream流操作集合交集,差集,并集,过滤,分组,去重,排序,聚合等

测试对象 public class Person {private String name;private Integer age;private Integer weight;public Person() {}public Integer getWeight() {return weight;}public void setWeight(Integer weight) {this.weight weight;}public Integer getAge() {return age…

第七节:利用CancellationTokenSource实现任务取消和利用CancellationToken类检测取消异常。

一. 传统的线程取消 所谓的线程取消&#xff0c;就是线程正在执行的过程中取消线程任务。 传统的线程取消&#xff0c;是通过一个变量来控制&#xff0c;但是这种方式&#xff0c;在release模式下&#xff0c;被优化从cpu高速缓存中读取&#xff0c;而不是从内存中读取&#xf…

start()和run()的区别

start方法&#xff1a; 通过该方法启动线程的同时也创建了一个线程&#xff0c;真正实现了多线程。无需等待run()方法中的代码执行完毕&#xff0c;就可以接着执行下面的代码。此时start()的这个线程处于就绪状态&#xff0c;当得到CPU的时间片后就会执行其中的run()方法。这个…

c#中的BeginInvoke和EndEndInvoke 摘要

摘要 异步这东西&#xff0c;真正用起来的时候&#xff0c;发现事情还是挺多的&#xff0c;最近在项目中用到了异步的知识&#xff0c;发现对它还是不了解&#xff0c;处理起来&#xff0c;走了不少弯路。觉得还是补一补还是很有必要的。 MSDN原文地址&#xff1a;https://ms…

关于@DateTimeFormat 和 @JsonFormat 注解

两个参数都是针对日期格式化做处理 1.入参格式化DateTimeFormat 传入参数是 String 类型,接收的参数Date 类型&#xff0c;类型无法转换。 使用 Spring 的 DateTimeFormat 注解格式化参数 传入参数要是日期格式的String 类型 例如:"2021-10-01" pattern &quo…

NET 提供了执行异步操作的三种模式

1.APM模式简介 在.net1.x的版本中就可以使用IAsyncResult接口实现异步操作&#xff0c;但是比较复杂&#xff0c;这种称之为异步编程模型模式 (Asynchronous Programming Model, APM)&#xff0c;也称为IAsyncResult模式 在这种APM模式下&#xff0c;一个同步操作XXX需要定义B…

java实体类属性非空判断工具类

import java.util.Collection; import java.util.HashMap; import java.util.Map; import java.util.Map.Entry;public class CheckParametersUtil {Map<String, Object> map new HashMap<>();/*** 添加需要校验的参数* param object 实参* param parameterName 参…

第八节:Task的各类TaskTResult返回值以及通用线程的异常处理方案。

一. Task的各种返回值-Task<TResult> PS&#xff1a; 在前面章节&#xff0c;我们介绍了Task类开启线程、线程等待、线程延续的方式&#xff0c;但我们并没有关注这些方式的返回值&#xff0c;其实他们都是有返回值的Task<TResult>&#xff0c;然后可以通过Task的…

第九节:深究并行编程Parallel类中的三大方法 (For、ForEach、Invoke)和几大编程模型(SPM、APM、EAP、TAP)

一. 并行编程 1. 区分串行编程和串行编程 ①. 串行编程&#xff1a;所谓的串行编程就是单线程的作用下&#xff0c;按顺序执行。(典型代表for循环 下面例子从1-100按顺序执行) ②. 并行编程&#xff1a;充分利用多核cpu的优势&#xff0c;同时开启多个线程并行执行。(典型代表…

Mybatis四种分页方式

1.数组分页 查询出全部数据&#xff0c;然后再list中截取需要的部分。 mybatis接口 List<Student> queryStudentsByArray(); xml配置文件 <select id"queryStudentsByArray" resultMap"studentmapper">select * from student</select&…

第十节:利用async和await简化异步编程模式的几种写法

一. async和await简介 PS&#xff1a;简介 1. async和await这两个关键字是为了简化异步编程模型而诞生的&#xff0c;使的异步编程更简洁&#xff0c;它本身并不创建新线程&#xff0c;但在该方法内部开启多线程&#xff0c;则另算。 2. 这两个关键字适用于处理一些文件IO操作。…

第十一节:深究用户模式锁的使用场景(异变结构、互锁、旋转锁)

一. 锁机制的背景介绍 本章节&#xff0c;将结合多线程来介绍锁机制&#xff0c; 那么问题来了&#xff0c;什么是锁呢&#xff1f; 为什么需要锁&#xff1f; 为什么要结合多线程来介绍锁呢&#xff1f;锁的使用场景又是什么呢&#xff1f; DotNet中又有哪些锁呢&#xff1f; …

第十三节:实际开发中使用最多的监视锁Monitor、lock语法糖的扩展、混合锁的使用(ManualResetEvent、SemaphoreSlim、ReaderWriterLockSlim)

一. 监视锁(Monitor和lock) 1. Monitor类&#xff0c;限定线程个数的一把锁&#xff08;Synchronized lock是他的语法糖&#xff09;&#xff0c;两个核心方法&#xff1a; Enter&#xff1a;锁住某个资源。 Exit&#xff1a;退出某一个资源。 测试案例&#xff1a;开启5个线…

什么是Mybatis ?

使用JDBC连接数据库 半自动持久层的ORM框架(因为要自己手写sql) 可以使用xml配置,可以使用注解. 优点:1.低耦合,sql重用,编写灵活 2.减少冗余代码 3.兼容数据库 4.能很好的与spring集成 5.提供映射标签,支持对象与数据库的ORM字段映射 缺点:1.sql需要自己编写 2数据库移植性…

第十四节: 介绍四大并发集合类并结合单例模式下的队列来说明线程安全和非安全的场景及补充性能调优问题。

一. 四大并发集合类 背景&#xff1a;我们目前使用的所有集合都是线程不安全的 。 A. ConcurrentBag&#xff1a;就是利用线程槽来分摊Bag中的所有数据&#xff0c;链表的头插法,0代表移除最后一个插入的值. (等价于同步中的List) B. ConcurrentStack&#xff1a;线程安全的St…

#{} 跟${}的区别

#{}是预编译处理 ,可以防止sql注入 ,提高安全性 mybatis 会把sql中的#{}替换成? 调用PreparedStatement set方法赋值 ${}是字符串替换 mybatis会把${}直接替换成变量值