并发编程
2018-08-19 18:02:23 8 举报
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 条评论
下一页