并发编程
2015-11-23 22:54:25 10 举报
AI智能生成
并发编程是一种程序设计技术,它允许多个计算过程或任务同时进行。这种技术的主要优点是可以提高系统的响应速度和处理能力,因为它可以充分利用多核处理器的优势。并发编程的主要挑战在于需要精确地控制和管理各个任务之间的交互,以避免数据竞争和其他潜在问题。常见的并发编程模型包括多线程、多进程和事件驱动等。并发编程在许多领域都有广泛的应用,如网络服务器、数据库系统、图形用户界面和游戏开发等。
作者其他创作
大纲/内容
多线程优势
提升资源利用率和系统吞吐率
发挥多处理器的强大能力
风险
活跃性问题,多线程中可能会出现进程死锁的情况
安全性问题,对于非线程安全的程序执行过程可能不可预测
性能,多线程会带来性能上的开销
线程安全性
概念:无论运行环境采用何种调度方式或者这些线程将如如何交替执行,在主调代码中不需要任何额外的同步或协同,这个类都能表现出正确的行为,称为线程安全类
核心在于对状态访问操作的管理,特别是共享和可变的状态的访问
共享表示多个线程同时访问,可变表示变量的值在其声明周期内可以发生变化
无状态对象一定是线程安全,即类中没有任何成员变量,也没有对其他类中成员变量的引用
由于不恰当的执行时序而出现不正确的结果,称之为竞态条件
最常见的为'先检查后执行',check-then-act
复合操作,++i等都为复合操作,必须引入必要的同步机制保证线程安全
加锁机制
内置锁,即synchronized block,是一种互斥锁;内置锁可重入,即如果某个线程视图获得一个已经由它自己持有的锁,这个请求就会成功
对于可能被多个线程同时访问的可变状态变量,访问它时都需要持有同一个锁
权衡简单性和性能之间的关系,避免出现不良并发与应用
对象共享
可见性
当一个线程修改对象状态后其它线程能够看到发生的状态变化
在没有同步的情况下,编译器处理器都可能对操作的执行顺序进行调整,而引发意想不到的情况
volatile变量,用来确保变量的更新操作通知到其他线程
声明为volatile后,编译器不会对该变量上的操作重新排序,不会缓存在寄存器或者其他处理器看不到的地方
典型用法:检查某个状态标识以判断是否退出循环
volatile变量不能保证操作的原子性,使用volatile变量要满足三个条件
对变量的写入操作不依赖变量的当前值,或者保证只有单线程更新变量的值
该变量不会跟其他状态变量一起纳入不变性条件
在访问变量时不需要加锁
发布与逸出
发布对象指使对象能够在当前作用域之外的代码中执行
发布一个对象后,在该对象的非私有域中引用的所有对象都会被发布
不要隐式的使this引用逸出;不要在构造器中使this引用逸出
线程封闭,即不共享数据
ad-hoc线程封闭,线程封闭的职责由程序来承担
栈封闭,只有通过局部变量才能访问对象
ThreadLocal类,用于对可变单实例变量或者全局变量进行共享
不变性
满足下面条件对象才是不可变的
对象创建以后其状态就不能修改
对象所有域都是final
对象是正确创建的(没有在创建时this引用逸出)
对象组合
设计线程安全类
收集同步需求
下一个状态依赖于当前状态,这个操作必定会是复合操作
依赖状态操作
基于状态的先验条件,例如不能从空的队列中删除元素
状态所有权
实例封闭
将数据封装在对象内部,将数据的访问限制在对象的方法上
内置锁,synchronized
java类库里的容器线程啊全包装类
线程安全性委托
利用线程安全类组合对象
当类中有复合操作,仅仅使用委托不足以实现线程安全性,必须提供加锁机制保证复合操作为原子操作,除非整个复合操作都可以委托给状态变量
在现有线程安全类中添加功能
通过组合实现添加功能
基础构建模块
同步容器类
同步容器执行check-then-act操作时,没有客户端加锁也是线程安全的,但当多个线程修改容器时,可能会出现意料之外的情况
迭代器和ConcurrentModificationException
如果在迭代期间计数器被修改,执行hasNext和next将抛出ConcurrentModificationException
隐藏的迭代器
容器的toString()方法,equals,hashCode等方法都可能抛出ConcurrentModificationException
并发容器
通过并发容器代替同步容器可以极大的提高伸缩性并降低风险
例如ConcurrentHashMap,CopyOnWriteArrayList,Queue,BlockingQueue等
双端队列,Deque,BlockingDeque
生产者与消费者
用阻塞队列支持生产者和消费者模式,将数据的生产和使用过程解耦来简化工作负担
使用双端队列,支持工作秘取,既每个消费者都有一个双端的工作队列,当某个消费者完成自己队列的全部工作,可以从其他消费者的双端队列末尾秘密的取得工作
阻塞方法和中断方法
Thread提供interrupt方法用于中断县城或者查询线程是否已经被中断
当代码调用了一个会抛出interruptedException异常的方法时,该方法自己就变成了一个阻塞方法
传递异常
恢复中断
同步工具类
闭锁
延迟线程的进度直到其到达终止状态
CountDownLatch
FutureTask
Semaphore,信号量,用来控制同时访问某个特定资源的操作数量
栅栏,CyclicBarrier,所有线程同时到达栅栏位置才能继续执行
结构化并发应用程序
0 条评论
下一页