并发编程的艺术第一章

1.1上下文切换

        CPU通过给每个线程分配CPU时间片来实现这个机制。

        当前任务执行一个时间片后会切换到下一个任务。但是,在切换前会保存上一个任务的状态,以便下次切换回这个任务时,可以再加载这个任务的状态。所以任务从保存到再加载的过程就是一次上下文切换。

1.1.1多线程一定快吗

        当并发执行累加操作不超过百万次时,速度会比串行执行累加操作要慢。

        原因:线程有创建和上下文切换的开销。

1.1.2 测试上下文切换次数和时长

        使用Lmbench3 [1]可以测量上下文切换的时长。

        使用vmstat可以测量上下文切换的次数。

1.1.3 如何减少上下文切换
  • 无锁并发编程。多线程竞争锁时,会引起上下文切换,所以多线程处理数据时,可以用一 些办法来避免使用锁,如将数据的ID按照Hash算法取模分段,不同的线程处理不同段的数据。
  • CAS算法。Java的Atomic包使用CAS算法来更新数据,而不需要加锁。
  • 使用最少线程。避免创建不需要的线程,比如任务很少,但是创建了很多线程来处理,这样会造成大量线程都处于等待状态。
  • 协程:在单线程里实现多任务的调度,并在单线程里维持多个任务间的切换。
1.1.4 减少上下文切换实战

        1,用jstack命令dump线程信息

        2,

        

1.2 死锁

        在一些更为复杂的场景中,比如t1拿到锁之后,因为一些异常情况没有释放锁 (死循环)。又或者是t1拿到一个数据库锁,释放锁的时候抛出了异常,没释放掉。

        预防避免:

        1.互斥条件:一个资源每次只能被一个进程使用。

        2.请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放;

                破坏:首次执行一次性申请所有的资源。

        3.不剥夺条件:进程已获得的资源,在末使用完之前,不能强行剥夺;

                破坏:占用部分资源的线程申请其他资源的时候申请不到,主动释放自己持有的资源。

        4.循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系;

                破坏:按序申请,给资源编号,所有线程可以按照线性化的序号顺序去申请共享资源。

        数据库死锁:
                避免:

                1,应尽可能缩短事务。在同一DB中并发执行多个需要长时间运行的事务时,发生死锁的概率较大。事务运行时间越长,其持有排它锁(exclusive锁)或更新锁(update锁)的时间便越长,从而堵塞了其它活动并可能导致死锁。保持事务在一个批处理中,可以最小化事务的网络通信往返量,减少完成事务可能的延迟并释放锁。同时,涉及多个表的查询更新操作,若比较耗时,尽量不要放在一个事务内处理,能分割便分割。若不能分割,便尽可能使之在业务量较小的时间(例如子夜或者午餐时间)执行。

                2,应按同一顺序访问数据对象。如果所有并发事务按同一顺序访问对象,则发生死锁的可能性会降低。(不同线程迫按相同顺序排队获取资源)

                3,避免编写包含用户交互的事务。防止因用户交互反馈导致的事务的阻塞挂起。也会英雄系统吞吐量。

                4,可使用低隔离级别使用较低隔离级别可以缩短持有共享锁的时间,降低锁的争夺。

                5,项目体系结构的优化。如采用效率较高的计算模型。复杂的业务采用异步任务调度处理。

                6,主从复制,读写分离。

                死锁检测死锁超时机制:

                越复杂的系统,比如innodb,越能检测到死锁的循环依赖,并立即返回一个错误。另外一种解决,当查询的时间达到等待超时的设定后放弃锁请求,这种通常不太好。

                Innodb目前处理的方式是,将持有最少的行级排它锁的事务进行回滚(相对比较简单)。死锁发生以后,只有部分或完全回滚其中一个事务,才能打破死锁。对于事务型的系统,这是无法避免的,所以应用程序在设计时必须考虑如何处理死锁。大多数情况下只需要重新执行因死锁回滚的事务即可。

        

1.3 资源限制的挑战
1.3.1,什么是资源限制

        资源限制是指在进行并发编程时,程序的执行速度受限于计算机硬件或软件资源

  • 硬件资源限制,比如带宽的上传/下载速度、硬盘读写速度和CPU的处理速度。
  • 软件资源限制,比如数据库的连接 数和socket连接数等。
1.3.2,资源限制引发的问题

        将某段串行的代码并发执行,因为受限于资源,仍然在串行执行,这时候程序不仅不会加快执行,反而会更慢,因为增加了上下文切换和资源调度的时间。

1.3.3,如何解决资源限制的问题

        对于硬件资源限制,可以考虑使用集群并行执行程序。比如使用ODPS(ODPS支持大规模批量计算、实时分析等服务,提供实时流式计算、机器学习等多种计算能力,可同时调度超10万台以上服务器规模进行并行计算Hadoop(充分利用集群的威力进行高速运算和存储或者自己搭建服务器集群,不同的机器处理不同的数据。可以通过“数据ID%机器数”,计算得到一个机器编号,然后由对应编号的机器处理这笔数据。

        对于软件资源限制,可以考虑使用资源池将资源复用。比如使用连接池将数据库和Socket 连接复用,或者在调用对方webservice接口获取数据时,只建立一个连接。

1.3.4,在资源限制情况下进行并发编程

        根据不同的资源限制调整 程序的并发度。

        

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值