了解一些多线程相关的知识
2019独角兽企业重金招聘Python工程师标准>>>
一、基础知识
a)多线程的基础类为Thread,实际应用中一般用线程池,而不会直接用到Thread类。Thread基本的使用为:
int i = 5;
Thread thread = new Thread((p) => {
Console.WriteLine(p);
});
thread.Start(i);
可以用lambda写法,也可以指向一个方法,参数通过Start(i)来传递。
b) 线程间的同步有几种方法
可以在一个方法加上[MethodImpl(MethodImplOptions.Synchronized)],这样这个方法就无法被多个线程同时访问了,这属于方法粒度的控制。
lock和Monitor可以提供代码块粒度的控制,用lock(<locker>){}或Monitor.Enter(<locker>)\Monitor.Exit(<locker>)包围的代码块可以做到只允许一个线程同时访问。
c) 对于单例模式,如果要保证线程安全,最好用这样的写法:
class Singleton {
private Singleton() { }
private static object locker = new object();
private static Singleton instance = null;public static Singleton GetSingleton() {
if (instance == null) {
lock (locker) {
instance = new Singleton();
}
}
return instance;
}
}
需要注意的是,只有在instance==null的时候,才进行lock并初始化。
d)线程的控制和线程池
除了锁之外,还可以通过ManualResetEvent、AutoResetEvent来进行线程间的的通讯,以进行更精细的控制。基本的方法为WaitOne、Set、Reset
AutoResetEvent are = new AutoResetEvent(false);
Thread t1 = new Thread(() => {
while (true) {
Console.WriteLine("waitting open");
are.WaitOne();
Console.WriteLine("Open");
}
});
在这里使用WaitOne就相当于为线程的流动加上了闸门,然后配合Set、Reset就可以控制线程的通断了。
一般的场景推荐应用线程池。线程池中的线程使用完后不会被销毁,而是被回收,供下一次使用,这样可以节省反复创建、销毁线程造成的开销。线程池不追求精细化的控制,但能够提供简单的使用多线程的方式,自动进行性能调优,很适合于UI程序中避免程序假死。
二、三种异步编程模型
三种异步编程模型分别为EAP、APM、TPL,TPL方式使用最简洁。
a) EAP(Event-based Asynchronous Pattern)方式使用简单,但不容易实现复杂逻辑,已不推荐使用。EAP使用回调的写法:
private static void EAP() {
WebClient wc = new WebClient();
wc.DownloadStringCompleted += Wc_DownloadStringCompleted;
wc.DownloadStringAsync(new Uri("http://www.github.com"));
Console.WriteLine("Downloading");
}
private static void Wc_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e) {
Console.WriteLine(e.Result);
}
b) APM(Asynchronous Programming Model)方式也不推荐使用了,FileStream还保留有这种写法:
private static void APM() {
string filePath = "e:EFCore.txt";
using (var fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read)) {
var buffer = new byte[128];
var asyncState = new AsyncState { FS = fileStream, Buffer = buffer, EvtHandle = new ManualResetEvent(false) };
IAsyncResult asyncResult = fileStream.BeginRead(buffer, 0, buffer.Length, new AsyncCallback(AsyncReadCallBack), asyncState);
asyncState.EvtHandle.WaitOne();
Console.WriteLine();
Console.WriteLine("read complete");
Console.ReadKey();
}
}public static void AsyncReadCallBack(IAsyncResult asyncResult) {
var asyncState = (AsyncState)asyncResult.AsyncState;
int readCn = asyncState.FS.EndRead(asyncResult);
if (readCn > 0) {
byte[] buffer;
if (readCn == 128) {
buffer = asyncState.Buffer;
}
else {
buffer = new byte[readCn];
Array.Copy(asyncState.Buffer, 0, buffer, 0, readCn);
}
string readContent = Encoding.UTF8.GetString(buffer);
Console.Write(readContent);if (readCn < 128) {
asyncState.EvtHandle.Set();
}
else {
Array.Clear(asyncState.Buffer, 0, 128);
asyncState.FS.BeginRead(asyncState.Buffer, 0, 128, new AsyncCallback(AsyncReadCallBack), asyncState);
}
}
}
c) TPL(Task Parallel Library)是在.Net4.0之后的新特性,异步实现起来更简洁、直观。比如FileStream的使用:
async static void TPL() {
string filePath = "e:/文章汇总/083.20170906 .Net Core(二)EFCore.txt";
using (var fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read)) {
var buffer = new byte[128];
var readLength = 0;
while ((readLength = await fileStream.ReadAsync(buffer, 0, buffer.Length)) != 0) {
string content = Encoding.UTF8.GetString(buffer);
Console.WriteLine(content);
}
Console.WriteLine("complete");
}
}
方法要被被async修饰,同时fileStream前使用await,然后就可以用很自然的的编码方式了。WinForm中的事件处理方法、MVC中的Action都可以使用这种方法。
学习资料:如鹏网.net提高班http://www.rupeng.com/News/10/4603.shtml
转载于:https://my.oschina.net/u/2327858/blog/1539514
了解一些多线程相关的知识相关推荐
- 面试中常问多线程相关的知识,在工作中到底用在哪里呢?
求职面试中,面试官问到了高并发相关问题,该怎么办? 如果在求职面试的过程中,面试官问了你这个方向的问题,那你必须打起十二分的精神来回答这个问题,毕竟在各大厂招聘的JD中都提到了求职者具备[高并发经验] ...
- iOS多线程编程的知识梳理
多线程编程也称之为并发编程,由于其作用大,有比较多的理论知识,因此在面试中也是受到面试官的青睐.在日常项目开发中,至少网络请求上是需要使用到多线程知识的,虽然使用第三方的框架比如AFNetworkin ...
- Java多线程相关知识【17】--设计模式--上下文模式(Context)
文章目录 Java多线程相关知识[17]--设计模式--上下文模式(Context) 1. 问题的引入 2. 解决方法 1. 解决理论 2. 实操代码 上下文数据保存 上文 下文 调度者 测试上下文 ...
- Java多线程相关的几十个问题
转载来源:http://www.cnblogs.com/HadesFX/p/5333810.html , https://www.cnblogs.com/HadesFX/p/5333820.html ...
- JAVA相关编译知识
JAVA相关编译知识 总览 语言进化史 整体流程 编译器整体流程 词法分析 语法分析 语义分析 中间代码生成 目标代码生成器 代码优化 编译相关知识 编译种类 热点探测技术 编译什么 什么时候进行检测 ...
- 黑马程序员_JAVA相关基础知识
------- android培训.java培训.期待与您交流! -------- JAVA相关基础知识 1.面向对象的特征有哪些方面 1.抽象: 抽象就是忽略一个主题中与当前目标无关的那些方面,以便 ...
- Java集合、IO、多线程的一些知识
Java集合 集合总图概览 Collection Collection 分为List<E>接口和Set<E>接口. 共有的常见方法 添加: boolean add(Object ...
- 【C++后台开发面经】面试总结第三波:针对后台开发相关基础知识分类总结
前言 面试总结第三波,关于后台开发面试相关基础知识,数据结构.算法.linux操作系统.计算机网络.C++.数据库进行分类总结. 后端面试总结 目录 后端面试总结 1.数据结构 链表和数组的区别 树的 ...
- mysql bdb版本_深入理解mysql之BDB系列(1)---BDB相关基础知识
深入理解mysql之BDB系列(1) ---BDB相关基础知识 作者:杨万富 一:BDB体系结构 1.1.BDB体系结构 BDB总体的体系结构如图1.1所看到的,包括五个子系统(见图1.1中相关数). ...
最新文章
- 你真的懂用户画像吗?
- #运算符、不同的指针类型、数组和指针、指针运算、堆、栈、静态区、只读区、下标VS指针...
- python-三层神经网络的分类回归问题
- ios高效开发-正确的使用枚举(Enum)
- MySQL中事务的分类
- Bailian2806 公共子序列【最长公共子序列+DP】
- n 中选 m —— 随机采样的艺术
- 浏览器内核选型列表,请大家继续补充
- Python使用datetime模块进行简单的日期换算与计算
- tcpdf html 格式重叠,使用TCPDF进行HTML呈现(PHP)
- [asp.net]自定义控件(数据绑定)
- 联想z510笔记本拆机
- Android对话框集合
- 《鸟哥的Linux私房菜》chapter7 20180827~20180831
- 基于ArcGIS Pro、Python、USLE、INVEST模型等多技术融合的生态系统服务构建生态安全格局
- 俄罗斯方块30周年 设计者忆当年
- 华为路由器:ipsec技术
- 同态加密在联邦计算中的应用
- 闲置路由器怎么利用起来?
- twitter账号被冻结如何申诉,已成功解冻(我是第一次被冻结,听闻二次冻结会永久冻结)