多线程开发要点(三) 并发模式 多线程开发中,并发控制基本上都会使用到。 并发在使用上还是有很多技巧的。POSA2中总结了很多并发模式。 其实这些模式在编码中均使用过,作者总结出来,对于理清思路, 整理知识点还是非常有用的。 1. 定界加锁 scoped locking 实现: 利用c++语言对象的自动解构特点,实现同步锁自动解锁。 优点: 1. 增加了程序的健壮性,防止开发者在异常退出忘记解锁的错误。 缺点: 1. 受语言相关语意的限制。该方法主要基于c++语言。 虽然该模式是在对象析构的过程进行解锁。对象析构一般发生在 函数的退出。但是这是基于C++(www.cppentry.com)的。如果使用C语言的longjmp(), 函数直接退出执行栈而没有按栈退出,解锁不会执行。 同理,在线程执行过程中,在同步函数中,调用pthread_exit() 退出函数时, 对象也不会被解构。 进程中,直接调用exit(),如果是一个进程级别的同步锁,该锁 也不会被解锁。 2. 同步函数不能递归的调用自己,这样会引发自死锁。 2. 策略化加锁 strateagized locking 实现: 通过多态性或者是参数化类型实现。通过策略模式实现不同锁的实现。 优点: 1. 增加灵活性和个性化。 策略模式本身的意图就是封装变化。 2. 降低组件的维护代价。 因为对于各种并发模型只有一份代码实现。 3. 改善重用性 因为这种模式实现的组件不太依赖与具体的同步机制。 缺点: 1. 强行加锁 2. 过分工程化 3. 线程安全接口模式加锁 thread-safe interface pattern locking 实现: 将类接口中提供的同步接口方法与具体功能实现方法分离。提供同步接口方法的 实现主要是加锁,解锁。而具体功能实现的方法,只是功能代码。通过添加新的 内部私有函数实现功能代码。而且应尽量让功能代码粒度减小。 在锁的使用上,应该尽量减小代码的粒度,将关键代码缩减的越小,对锁的争用 也会减少。 模式对比 decorator pattern 将功能代码实现成功能类,在使用装饰模式,进行加锁控制。 不过,装饰者模式是动态增加额外的责任扩展一个对象。 线程安全模式目标类似,但是增加了健壮的,有效的加锁策略,以史组件线性安全。 静态的划分方法责任。 优点: 1. 提高了健壮性。 避免了组件间方法调用的引起的死锁问题。 2. 改善性能 确保在必要的时候进行加解锁。 3. 简化了软件 将加锁与功能特性分开。 缺点: 1. 增加了函数调用开销。 2. 仍然存在潜在的死锁。 3. 存在对象间私有方法的误用。 4. 双检查加锁优化 double check locking opimization 实现: 通过条件检查避免不必要的加锁操作,从而减少了自由的争用,提高性能。 |