一. 并行编程

1. 区分串行编程和串行编程

  ①. 串行编程:所谓的串行编程就是单线程的作用下,按顺序执行。(典型代表for循环 下面例子从1-100按顺序执行)

  ②. 并行编程:充分利用多核cpu的优势,同时开启多个线程并行执行。(典型代表Parallel.For循环 下面例子从1-100无序执行)

 代码实践:

   {
//1. 串行 (从1-100按顺序执行)
for (int i = ; i < ; i++)
{
Console.WriteLine(i);
}
//2. 并行 (从1-100无序执行)
Parallel.For(, , (item) =>
{
Console.WriteLine(item);
});
}

结论:串行的代码按顺序依次输出,并行的代码无顺序输出。

2. 深究Parallel类中的方法 (For方法、ForEach方法、Invoke方法 这三个方法都是用来开启线程的)

(1). Invoke方法

  a. 该方法的作用就是用来同时开启多个线程的。

  b. 该方法有两个重载,主要涉及到两个参数,用来配置最大并行数(即线程数)和一个可变的Action委托数组(详见源码)。

案例一: 开启五个不同的线程调用五个方法

我们发现一个现象,主线程等着这五个子线程执行完毕后才执行,但是我们并没有写线程等待的代码,所以我们可以总结:

①:并行计算,开启多个线程后,不需要再开辟线程等待,直接是主线程完成后续操作。

②:而普通多线程执行后,需要单独再开辟一个线程等待,然后主线程在执行。

 代码实践:

                 {
Parallel.Invoke(() => this.TestThread("bct1")
, () => this.TestThread("bct2")
, () => this.TestThread("bct3")
, () => this.TestThread("bct4")
, () => this.TestThread("bct5")
);
}

案例二: 指定最大并行数进行线程调用

我们发现,五个任务中的四个任务同时由不同线程开启,当其中一个任务结束时,第五个任务开启,并由刚结束的任务的线程来执行。

                {
//设置最大的线程并行数
ParallelOptions p = new ParallelOptions();
p.MaxDegreeOfParallelism = ; Parallel.Invoke(p, () => this.TestThread("bct1")
, () => this.TestThread("bct2")
, () => this.TestThread("bct3")
, () => this.TestThread("bct4")
, () => this.TestThread("bct5")
);
}

(2). For方法 (前两个参数之间的差代表任务的个数)

  这里介绍一个简单重载: public static ParallelLoopResult For(int fromInclusive, int toExclusive, Action<int> body);

  fromInclusive:开始索引(含).

  toExclusive:结束索引(不含).

  body:将为每个迭代调用一次的委托.

当然该方法中的其他重载中也有很丰富的功能,比如也可以配置最大线程数。

代码实践:

  {
//案例一:前两个参数之间的差,就为并行计算线程的个数
{
Parallel.For(, , t =>
{
//这里的t分别为:5,6,7,8,9 五个数
string name = string.Format("bct{0}", t);
this.TestThread(name);
});
}
//案例二: 配置最大并行数
//结果:同时最多5个线程执行,但是还是要执行9个任务,(6,7,8,9,10,11,12,13,14),后面四个任务等前面的执行完后,再执行
{
ParallelOptions po = new ParallelOptions()
{
MaxDegreeOfParallelism = //表示最大线程数为5,后面即使配置超过5,也无效
};
Parallel.For(, , po, (t, state) =>
{
string name = string.Format("bct{0}", t);
this.TestThread(name);
//state.Break(); //退出单次循环(没看到实际作用)
// state.Stop(); //退出全部循环(没看到实际作用)
//return;
});
}
}

(3). ForEach方法

  这里也是介绍一个简单的重载:int数组中的个数代表需要进行并行任务的个数,但并不一定所有任务同时执行,也不一定每个任务都是一个新线程执行。

该方法当然也可以配置最大并行数。

 代码实践:

 {
//数组里的个数,就为并行进行并行任务数
Parallel.ForEach(new int[] { , , , , }, t =>
{
//这里的t分别为:3, 5, 44, 55, 100五个数
string name = string.Format("bct{0}", t);
this.TestThread(name);
}
}

二. 常见的编程模型

1.同步编程模型(SPM):单线线程、串行开发模式。

2.异步编程模型(APM):xxxbegin、xxxend的模式。

3.基于事件的编程模型(EAP): xxAsync这样的事件模式。 eg:WebClient。

4.基于Task的编程模型(TAP): APM和EAP都可以使用Task来实现,微软的初衷就是想通过Task大一统异步编程领域。

下面分享两段代码,不做深入研究了。

             {
FileStream fs = new FileStream(Environment.CurrentDirectory + "//1.txt", FileMode.Open);
var bytes = new byte[fs.Length];
var task = Task.Factory.FromAsync(fs.BeginRead, fs.EndRead, bytes, , bytes.Length, string.Empty); var nums = task.Result; Console.WriteLine(nums);
}
{
FileStream fs = new FileStream(Environment.CurrentDirectory + "//1.txt", FileMode.Open); var bytes = new byte[fs.Length]; fs.BeginRead(bytes, , bytes.Length, (aysc) =>
{
var nums = fs.EndRead(aysc); Console.WriteLine(nums); }, string.Empty); Console.Read();
}

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

  1. Android 编程 AMapLocationClientOption 类中的 setNeedAddress 方法用处 (高德地图 com.amap.api.location.AMapLocationClientOption 中的类)

    最近在用高德地图来写Android App, 其中有一些 方法是不太理解的,这里写一下 对  高德地图  com.amap.api.location.AMapLocationClientOption ...

  2. 第8.6节 Python类中的__new__方法深入剖析:调用父类__new__方法参数的困惑

    上节<第8.5节 Python类中的__new__方法和构造方法__init__关系深入剖析:执行顺序及参数关系案例详解>通过案例详细分析了两个方法的执行顺序,不知大家是否注意到了,在上述 ...

  3. 第8.26节 重写Python类中的__getattribute__方法实现实例属性访问捕获

    一. 引言 在<第7.23节 Python使用property函数定义属性简化属性访问的代码实现>和<第7.26节 Python中的@property装饰器定义属性访问方法gette ...

  4. Java中是否可以调用一个类中的main方法?

    前几天面试的时候,被问到在Java中是否可以调用一个类中的main方法?回来测试了下,答案是可以!代码如下: main1中调用main2的主方法 package org.fiu.test; impor ...

  5. 重写Object类中的equals方法

    Object是所有类的父亲,这个类有很多方法,我们都可以直接调用,但有些方法并不适合,例如下面的student类 public class Student { //姓名.学号.年纪 private S ...

  6. PHP通过反射方法调用执行类中的私有方法

    PHP 5 具有完整的反射 API,添加了对类.接口.函数.方法和扩展进行反向工程的能力. 下面我们演示一下如何通过反射,来调用执行一个类中的私有方法: <?php //MyClass这个类中包 ...

  7. Java String类中的intern()方法

    今天在看一本书的时候注意到一个String的intern()方法,平常没用过,只是见过这个方法,也没去仔细看过这个方法.所以今天看了一下.个人觉得给String类中加入这个方法可能是为了提升一点点性能 ...

  8. Java线程状态及Thread类中的主要方法

    要想实现多线程,就必须在主线程中创建新的线程对象. 不论什么线程一般具有5种状态,即创建,就绪,执行,堵塞,终止. 创建状态: 在程序中用构造方法创建了一个线程对象后,新的线程对象便处于新建状态,此时 ...

  9. [SignalR]在非Hub继承类中使用脚本方法

    原文:[SignalR]在非Hub继承类中使用脚本方法 新建一个普通类OutHub,里面包含一个脚本方法OutHubTest. 因为大家知道,若能让脚本调用到的话,必须继承Hub,那怎么实现了?通过G ...

随机推荐

  1. markdown小知识总结

    字体.字号.颜色 但如果我们想修改文字大小/颜色/字体,就要用font标签,代码如下: 宋体大小为2的字 color代表字体颜色(要用16进制颜色值),size代表文字大小,face代表字体 效果展示 ...

  2. day 6 - 1 知识点小节

    python2 与 python3 的区别 1. print.input.生成器 #python2 print() print 'abc' range() xrange() 生成器 raw_input ...

  3. web 本地存储 (localStorage、sessionStorage)

    web 本地存储 (localStorage.sessionStorage,cookie) localStorage(长期储存):即使关闭浏览器数据也不会删除,除非使用localStorage.cle ...

  4. session和application内置对象

    一.Session内置对象 分析得知request内置对象中的属性只是在当次请求中有效,经过客户端跳转之后就无效,因为客户端跳转属于第二个请求,也就是说request只代表当次请求的对象,如果要让客户 ...

  5. [JLOI2015]骗我呢

    [JLOI2015]骗我呢 Tags:题解 作业部落 评论地址 TAG:数学,DP 题意 骗你呢 求满足以下条件的\(n*m\)的矩阵的个数对\(10^9+7\)取模 对于矩阵中的第\(i\)行第\( ...

  6. Lepus搭建企业级数据库慢查询分析平台

    前言 Lepus的慢查询分析平台是独立于监控系统的模块,该功能需要使用percona-toolkit工具来采集和记录慢查询日志,并且需要部署一个我们提供的shell脚本来进行数据采集.该脚本会自动开启 ...

  7. Gerrit 添加用户

    使用ssh添加用户 ssh name@localhost -p 29418 gerrit create-account username --email username@email --full-n ...

  8. Python中getopt()函数的使用

    在运行程序时,可能需要根据不同的条件,输入不同的命令行选项来实现不同的功能.目前有短选项和长选项两种格式.短选项格式为"-"加上单个字母选项:长选项为"--"加 ...

  9. 阿里云对象存储OSS与文件存储NAS的区别

    一.简介 应用场景:选择一款存储产品,面向文档数据的存取,不会涉及到数据处理. 产品选型主要从OSS和NAS中选择一款,满足文档存储的需求. 二.NAS优缺点 NAS 是一种采用直接与网络介质相连的特 ...

  10. AirBnB春招笔试题

    试题说明 笔试题只有一道,限时1小时. 模拟一个战争外交游戏,游戏中定义了三种操作: A city1 Hold : 军队A 占领了city1 A city1 Move city2 : 军队A从city ...