《Thinking in Java》读书笔记之并发(六)

来源:互联网 发布:网络机顶盒软件大片 编辑:程序博客网 时间:2024/05/21 17:25

共享受限资源

对于并发工作,你需要某种方式来防止两个任务访问相同的资源,至少关键阶段不能出现这种现象

基本上所有的并发模式在解决线程冲突问题的时候,都是采取序列化访问共享资源的方案

synchronized

java以提供关键字synchronized的形式,为防止资源冲突提供了内置支持
要控制对共享资源的访问,得先把它包装进一个对象

Lock

Lock对象必须显示的创建、锁定和释放。与synchronized的形式的相比,代码缺乏优雅性。但是,对于解决某些类型的问题来说。它更加灵活。

如果使用synchronized关键字,某些事物失败了,那么就会抛出一个异常。但是你没有机会去做任何清理工作。以维护系统使其处于良好状态。有了显示的Lock对象,你就可以使用finally子句将系统维护在正常的状态了。

volatile

JVM可以将64位(long和double变量)读取和写入当做两个分离的32来执行,这就产生了一个在读取和写入操作中间发生上下文切换,从而导致不同任务可以看到不正确的结果的可能性(这有时被称为字撕裂)

当定义long和double变量时,如果使用volatile关键字,就会获取原子性

如果一个域完全由synchronized方法或语句块来保护,那就不必将其设置为是volatile的

当一个域的值依赖于它之前的值时,volatile就无法工作了。如果某个域的值受到其他域的值的限制。那么volatile也无法工作。使用volatile而不是synchronized的唯一安全的情况是类中只有一个可变的域。

同步控制块

有时我们只希望防止多个线程同时访问方法内部的部分代码而不是防止访问整个方法,通过这种方式分离出来的代码段被称为临界区,她也使用synchronized关键字,这里synchronized被用来指定某对象,此对象的锁被用来对花括号内的代码进行同步控制

synchronized(syncObject){}

在进入此段代码前,必须得到syncObject对象的锁。如果其他线程也已经得到这个锁,那么就要等到锁被释放以后,才能进入临界区。

使用它的好处是,可以使多个任务访问对象的时间性能得到显著提高

ThreadLocal

防止任务在共享资源上产生冲突的第二种方式是根除对变量的共享,线程本地是一种自动化机制,可以使用相同变量的每个不同线程都创建不同的存储,

get()方法将返回与其线程相关联的对象的副本,而set()会将参数数据插入到为其线程储存的对象中。

0 0
原创粉丝点击