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

了解一些多线程相关的知识相关推荐

  1. 面试中常问多线程相关的知识,在工作中到底用在哪里呢?

    求职面试中,面试官问到了高并发相关问题,该怎么办? 如果在求职面试的过程中,面试官问了你这个方向的问题,那你必须打起十二分的精神来回答这个问题,毕竟在各大厂招聘的JD中都提到了求职者具备[高并发经验] ...

  2. iOS多线程编程的知识梳理

    多线程编程也称之为并发编程,由于其作用大,有比较多的理论知识,因此在面试中也是受到面试官的青睐.在日常项目开发中,至少网络请求上是需要使用到多线程知识的,虽然使用第三方的框架比如AFNetworkin ...

  3. Java多线程相关知识【17】--设计模式--上下文模式(Context)

    文章目录 Java多线程相关知识[17]--设计模式--上下文模式(Context) 1. 问题的引入 2. 解决方法 1. 解决理论 2. 实操代码 上下文数据保存 上文 下文 调度者 测试上下文 ...

  4. Java多线程相关的几十个问题

    转载来源:http://www.cnblogs.com/HadesFX/p/5333810.html , https://www.cnblogs.com/HadesFX/p/5333820.html ...

  5. JAVA相关编译知识

    JAVA相关编译知识 总览 语言进化史 整体流程 编译器整体流程 词法分析 语法分析 语义分析 中间代码生成 目标代码生成器 代码优化 编译相关知识 编译种类 热点探测技术 编译什么 什么时候进行检测 ...

  6. 黑马程序员_JAVA相关基础知识

    ------- android培训.java培训.期待与您交流! -------- JAVA相关基础知识 1.面向对象的特征有哪些方面 1.抽象: 抽象就是忽略一个主题中与当前目标无关的那些方面,以便 ...

  7. Java集合、IO、多线程的一些知识

    Java集合 集合总图概览 Collection Collection 分为List<E>接口和Set<E>接口. 共有的常见方法 添加: boolean add(Object ...

  8. 【C++后台开发面经】面试总结第三波:针对后台开发相关基础知识分类总结

    前言 面试总结第三波,关于后台开发面试相关基础知识,数据结构.算法.linux操作系统.计算机网络.C++.数据库进行分类总结. 后端面试总结 目录 后端面试总结 1.数据结构 链表和数组的区别 树的 ...

  9. mysql bdb版本_深入理解mysql之BDB系列(1)---BDB相关基础知识

    深入理解mysql之BDB系列(1) ---BDB相关基础知识 作者:杨万富 一:BDB体系结构 1.1.BDB体系结构 BDB总体的体系结构如图1.1所看到的,包括五个子系统(见图1.1中相关数). ...

最新文章

  1. 你真的懂用户画像吗?
  2. #运算符、不同的指针类型、数组和指针、指针运算、堆、栈、静态区、只读区、下标VS指针...
  3. python-三层神经网络的分类回归问题
  4. ios高效开发-正确的使用枚举(Enum)
  5. MySQL中事务的分类
  6. Bailian2806 公共子序列【最长公共子序列+DP】
  7. n 中选 m —— 随机采样的艺术
  8. 浏览器内核选型列表,请大家继续补充
  9. Python使用datetime模块进行简单的日期换算与计算
  10. tcpdf html 格式重叠,使用TCPDF进行HTML呈现(PHP)
  11. [asp.net]自定义控件(数据绑定)
  12. 联想z510笔记本拆机
  13. Android对话框集合
  14. 《鸟哥的Linux私房菜》chapter7 20180827~20180831
  15. 基于ArcGIS Pro、Python、USLE、INVEST模型等多技术融合的生态系统服务构建生态安全格局
  16. 俄罗斯方块30周年 设计者忆当年
  17. 华为路由器:ipsec技术
  18. 同态加密在联邦计算中的应用
  19. 闲置路由器怎么利用起来?
  20. twitter账号被冻结如何申诉,已成功解冻(我是第一次被冻结,听闻二次冻结会永久冻结)

热门文章

  1. 谷歌医疗AI再遭重挫!自宫头牌App,副总裁也已离职
  2. 李飞飞点赞「ARM」:一种让模型快速适应数据变化的元学习方法 | 开源
  3. 小鹏,该兑现PPT了
  4. 谷歌自研终端AI芯片曝出重大进展,联手三星,用于手机笔记本
  5. 微软更新Linux子系统,编译WSL 2内核只需3步
  6. cacti中监控squid的方法
  7. 云服务器 ECS快速入门:远程连接 ECS 实例
  8. 蚂蚁财富联手百会CRM全面升级金融服务
  9. web入门+书籍推荐
  10. JUnit 3.8 通过反射测试私有方法