关于Parallel我也不细说了,一则微软封装的很好用,二来介绍这个的遍地都是。

  我要说的是,要想成为一个优秀的标题党,一定要把重点放到别的地方,为了节省大家阅读时间,我先把结论说了,然后再慢慢从头说,愿意往下看的可以看看因果,不愿意看的,也算咱给大家提个醒吧。

  结论就是,大家在做单元测试用例的时候一定要用心,这篇随笔是要检讨并警醒下自己并与大家共勉。

  据一些我不记得名字的国外权威专家,据说是测试大师级人物研究,测试用例的出现的错误并不比被测试的代码少,我相信大多数人会和我类似,在写代码的时候小心翼翼,但是为代码编写单元测试及用例的时候往往注意力下意识的不那么集中,今天就是这么个情况。可能是缺乏锻炼(我天天打太极拳的。。。)的原因,连续几个晚上由于学习原因睡的比较晚,今天就比较困,然后干了件点题的事。

  我写了一个对象ID生成器,以时间戳和顺序号组合,虽然不支持集群,但是目前情况下足够了,然后因为复制数据库的同事坚决不同意将主键的int类型改掉,那怕改成bigint都不同意。。。跑题了。总之,各种限制的情况下出了这么个东西:

  //不能再集群情况下使用
public class IDGenerator
{
     private static double _seconds = 0;
private static int _sequenceIndex = 0;
private static object _lock = new object();
     private static ReaderWriterLockSlim writerLock = new ReaderWriterLockSlim();
private static IDGenerator _instance; private IDGenerator()
{
} public static int NewID
{
get
{
int newID = IDGenerator.Instance.CreateNewID();
return newID;
}
} private int CreateNewID()
{
string id; writerLock.EnterReadLock();
try
{
id = BuildIDAndUpdateSead();
}
finally//保证退出锁
{
writerLock.ExitReadLock();
}
int newID = TypeParseHelper.GetIntValueByString(id);
return newID;
} private string BuildIDAndUpdateSead()
{
double seconds;
bool isEqualSecondsCount;
seconds = InterceptSecondsInTicks(); isEqualSecondsCount = seconds.Equals(_seconds);
if (isEqualSecondsCount)
{
         bool isUpperBound = _sequenceIndex == ;
if (isUpperBound)
{
Thread.Sleep();
_sequenceIndex = ;
_seconds++;
}
          else
          {
  Interlocked.Increment(ref _sequenceIndex);
          }
}
else
            {
_seconds = seconds;
}
string id = _seconds.ToString() + _sequenceIndex.ToString().PadLeft(, '');
return id;
} private double InterceptSecondsInTicks()
{
DateTime currentDate = DateTime.Now;
long elapsedTicks = (currentDate.Ticks - ConstantGather.BEGIN_STANDARD_TICKS);
TimeSpan elapsedSpan = new TimeSpan(elapsedTicks);
double seconds = Math.Floor(elapsedSpan.TotalSeconds);
return seconds;
} private static IDGenerator Instance
{
get
{
if (_instance != null)
{
return _instance;
} lock (_lock)
{
if (_instance == null)
{
_instance = new IDGenerator();
}
} return _instance;
}
}
}

  做完了,当然要写点单元测试测试一下,就先写了个同步的,然后写了个异步的,然后写了个并发的

       public List<int> GenerateRequisitionIDs()
{
TaskFactory taskFactory = new TaskFactory();
Task<int>[] tasks = new Task<int>[] {
taskFactory.StartNew(() => GenerateRequisitionID()),
taskFactory.StartNew(() => GenerateRequisitionID()),
taskFactory.StartNew(() => GenerateRequisitionID()) }; var query = tasks.Where(t => !t.Result.Equals())
.Select(t => t.Result);
return query.ToList();
}

  高潮来了,然后我在单元测试里顺手写了个并行的。。。

Parallel.For(, actual, c =>
{
int id = target.GenerateRequisitionID();
list.AddLast(id);
});

  测试结果就不停得出错,我费了很大功夫定位到了出错的位置。。。

string idStr = _seconds.ToString() + "-" + _sequenceIndex.ToString().PadLeft(, '');

  这一句是我写了一堆定位错误的代码中的一句,发现了个奇怪的现象,这个字符串赋值后,两边居然是不一样的,而且这一句在排它锁里。。。

  并行的用法应该是将一对任务,平均分开,各自做各自的,互相不影响,问题就在于我这生成器是个单例。。。

  作为一个敬业的标题党,并发和并行的区别我就不说了,反正连百度都知道的事。。。  

  最后说一句,单元测试要认真,单元测试的代码哪怕随便玩的也要组织好,不要乱放,不要完全不着边的都测,正常业务里是不会有并行生成ID的场景的,这个测试没有意义,而且,如果看了生成器的代码会发现,由于int32本身的长度问题,我限定了一秒最多能生成999个ID,我需要测的其实不是并行问题,太晚了,思维比较跳跃,就这么着吧,下次长点记性就好了,以上。

Parallel并行之乱用的更多相关文章

  1. Parallel并行编程初步

    Parallel并行编程可以让我们使用极致的使用CPU.并行编程与多线程编程不同,多线程编程无论怎样开启线程,也是在同一个CPU上切换时间片.而并行编程则是多CPU核心同时工作.耗时的CPU计算操作选 ...

  2. C# IEnumerable,Lambda表达式和 Parallel并行编程的用法

    以前一直主要做C++和C方面的项目,对C#不太了解熟悉,但听说不难,也就一直没有在意学习C#方面的知识.今天有个C#项目,需要做些应用的扩展,同时修改一些bug.但看了C#代码,顿时觉得有些不适应了. ...

  3. Parallel并行编程

    Parallel并行编程 Parallel并行编程可以让我们使用极致的使用CPU.并行编程与多线程编程不同,多线程编程无论怎样开启线程,也是在同一个CPU上切换时间片.而并行编程则是多CPU核心同时工 ...

  4. C# 使用Parallel并行开发Parallel.For、Parallel.Foreach实例

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.N ...

  5. list.stream().parallel() 并行流

    https://blog.csdn.net/u011001723/article/details/52794455/  :  parallel()其实就是一个并行执行的流.它通过默认的ForkJoin ...

  6. Stream parallel并行流的思考

    1.并行流并不一定能提高效率,就和多线程并不能提高线程的效率一样 因为引入并行流会引起额外的开销,就像线程的频繁上下文切换会导致额外的性能开销一样,当数据在多个cpu中的处理时间小于内核之间的传输时间 ...

  7. .net Parallel并行使用注意事项

    因项目响应过慢,代码优化空间不大,在暂时无法调整系统架构的情况下,只有使用.NET中的TPL解决一些模块耗时过多的问题.但在使用过程中也碰到了一些问题,现在把它写下来,用于备忘. 1. Paralle ...

  8. .net Parallel并行使用

    因项目响应过慢,代码优化空间不大,在暂时无法调整系统架构的情况下,只有使用.NET中的TPL解决一些模块耗时过多的问题.但在使用过程中也碰到了一些问题,现在把它写下来,用于备忘. 1. Paralle ...

  9. oracle使用parallel并行,多线程查询

    insert into tmp (select /*parallel (a, 4)*/ * from plsuer.as_cdrindex_info_h partition(P_20170430) w ...

随机推荐

  1. 干货分享:SQLSERVER使用裸设备

    干货分享:SQLSERVER使用裸设备 这篇文章也适合ORACLE DBA和MYSQL DBA 阅读 裸设备适用于Linux和Windows 在ORACLE和MYSQL里也是支持裸设备的!! 介绍 大 ...

  2. [C#] 简单的 Helper 封装 -- SecurityHelper 安全助手:封装加密算法(MD5、SHA、HMAC、DES、RSA)

    using System; using System.IO; using System.Security.Cryptography; using System.Text; namespace Wen. ...

  3. 阿里云服务器上配置并使用: PHP + Redis + Mysql 从配置到使用

    (原创出处为本博客,http://www.cnblogs.com/linguanh/) 目录: 一,下载 二,解压 三,配置与启动 四,测试 Redis 五,配置 phpRedis 扩展 六,综合测试 ...

  4. Discuz论坛黑链清理教程

    本人亲测有效,原创文章哦~~~ 论坛黑链非常的麻烦,如果你的论坛有黑链,那么对不起,百度收录了你的黑链,不会自动删除,需要你手动去清理. 什么是黑链 黑链,顾名思义,就是一些赌博网站的外链,这些黑链相 ...

  5. Tomcat启动报错org.springframework.web.context.ContextLoaderListener类配置错误——SHH框架

    SHH框架工程,Tomcat启动报错org.springframework.web.context.ContextLoaderListener类配置错误 1.查看配置文件web.xml中是否配置.or ...

  6. QQ空间动态爬虫

    作者:虚静 链接:https://zhuanlan.zhihu.com/p/24656161 来源:知乎 著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出处. 先说明几件事: 题目的意 ...

  7. 纯javaScript、jQuery实现个性化图片轮播

    纯javaScript实现个性化图片轮播 轮播原理说明<如上图所示>: 1. 画布部分(可视区域)属性说明:overflow:hidden使得超出画布部分隐藏或说不可见.position: ...

  8. git

    CMD命令:git initgit add . [添加文件至暂存区]git commit -m '描述性语句 随意写即可'git branch gh-pages [创建仓库分支]git checkou ...

  9. TFS 生成配置

      生成  

  10. FineReport关于tomcat集群部署的方案

    多台服务器集群后,配置权限.数据连接.模板.定时调度等,只能每台服务器一个个配置,不会自动同步到所有服务器. 针对上述情况,在FineReport中提供新集群部署插件,将xml配置文件.finedb/ ...