读书笔记-----Java并发编程实战(一)线程安全性
线程安全类:在线程安全类中封装了必要的同步机制,客户端无须进一步采取同步措施
示例:一个无状态的Servlet
@ThreadSafe
public class StatelessFactorizer implements Servlet{
public void service(ServletRequest req,ServletResponse resp){
BigInteger i = extractFromRequest(req);
BigInteger[] factors = factor(i);
encodeIntoResponse(resp,factors);
}
}
这个类是无状态的,因为它既不包含任何域,也不包含任何对其他类中域的引用,计算过程中用到的变量是局部变量没有被共享。
无状态对象一定是线程安全的。
在并发编程中,由于不恰当执行时序而出现不正确结果的情况,称为竞态条件。
最常见的竞态类型就是先检查后执行操作:比如单例中的延迟初始化。
像递增,递减操作看上去只有一个操作,但这个操作并非原子的,会导致结果变得不可靠。这种情况称为:读取-修改-写入的复合操作,也是竞态类型的一种。
对于这些竞态条件类型的操作可以加上同步锁,或者使用一个现有的线程安全类。
如:
@ThreadSafe
public class CountingFactorizer implements Servlet{
private final AtomicLong count = new AtomicLong(0);
public long getCount(){return count.get();}
public void service(ServletRequest req,ServletResponse resp){
BigInteger i = extractFromRequest(req);
BigInteger[] factors = factor(i);
count.incrementAndGet();
encodeIntoResponse(resp,factors);
}
}
在java.util.concurrent.atomic包中包含了一些原子变量类,用于实现在数值和对象引用上的原子状态转换。
注意:当在不变性条件中涉及多个变量时,各个变量间并不是彼此独立的,而是某个变量的值会对其他变量的值产生约束。因此,当更新某一个变量时,需要在同一个原
子操作中对其他变量同时更新
重入:当某个线程请求一个由其他线程持有的锁时,发出的请求线程会被阻塞。然而内置锁是可以重入的,因此某个线程试图获得一个已经由他自己持有的锁,那么这个请求就会成
功。
这个过程可以描述为:线程请求一个未被持有的锁,JVM记下这个新的锁持有者,计数值置为1,当这个线程再次获取这个锁,计数值将递增。当线程退出同步代码块时,计数器会相
应的递减。当计数值为0时,这个锁将被释放。
示例:
public class Widget{
public synchronized void doSomething(){
...
}
}
public class LoggingWidget extends Widget{
public synchronized void doSomething(){
super.doSomething();
}
}
使用锁保护时,对于包含多个变量的不变性条件,其中涉及的所有变量都需要由同一个锁来保护。
注意:当执行时间较长的计算或者无法快速完成的操作时,一定不要持有锁。
读书笔记-----Java并发编程实战(一)线程安全性的更多相关文章
- java并发编程实战之线程安全性(一)
1.1什么是线程安全性 要对线程安全性给出一个确切的定义是非常复杂的.最核心的概念就是正确性.正确性:某个类的行为与其规范完全一致.在良好的规范中通常会定义各种不变性条件来约束对象的状态,以及定义各种 ...
- Java并发编程实战 之 线程安全性
1.什么是线程安全性 当多个线程访问某个类时,不管运行时环境采用何种调用方式或者这些线程将如何交替执行,并且在主调代码中不需要任何额外的同步或协同,这个类都能表现出正确的行为,那么就称这个类是线程安全 ...
- 读书笔记-----Java并发编程实战(二)对象的共享
public class NoVisibility{ private static boolean ready; private static int number; private static c ...
- 【java并发编程实战】-----线程基本概念
学习Java并发已经有一个多月了,感觉有些东西学习一会儿了就会忘记,做了一些笔记但是不系统,对于Java并发这么大的"系统",需要自己好好总结.整理才能征服它.希望同仁们一起来学习 ...
- Java并发编程实战 05等待-通知机制和活跃性问题
Java并发编程系列 Java并发编程实战 01并发编程的Bug源头 Java并发编程实战 02Java如何解决可见性和有序性问题 Java并发编程实战 03互斥锁 解决原子性问题 Java并发编程实 ...
- 《Java并发编程实战》读书笔记一 -- 简介
<Java并发编程实战>读书笔记一 -- 简介 并发的历史 并发的历史,也是人类利用有限的资源去提高生产效率的一个的例子. 设想现在有台计算机,这台计算机具有以下的资源: 单核CPU一个 ...
- Java并发编程的艺术读书笔记(2)-并发编程模型
title: Java并发编程的艺术读书笔记(2)-并发编程模型 date: 2017-05-05 23:37:20 tags: ['多线程','并发'] categories: 读书笔记 --- 1 ...
- Java并发编程的艺术读书笔记(1)-并发编程的挑战
title: Java并发编程的艺术读书笔记(1)-并发编程的挑战 date: 2017-05-03 23:28:45 tags: ['多线程','并发'] categories: 读书笔记 --- ...
- Java并发编程实战.笔记十一(非阻塞同步机制)
关于非阻塞算法CAS. 比较并交换CAS:CAS包含了3个操作数---需要读写的内存位置V,进行比较的值A和拟写入的新值B.当且仅当V的值等于A时,CAS才会通过原子的方式用新值B来更新V的值,否则不 ...
随机推荐
- 手把手教你从Core Data迁移到Realm
来源:一缕殇流化隐半边冰霜 (@halfrost ) 链接:http://www.jianshu.com/p/d79b2b1bfa72 前言 看了这篇文章的标题,也许有些人还不知道Realm是什么,那 ...
- angularjs 更新局部作用域
前几天项目需要,做了一个背景遮罩的弹出框,html采用js动态添加进去的,结果发现angularjs绑定在这里面不起作用,搜索下解决了,记录下: var smallApplyParent = docu ...
- PHP验证码的制作
<?phpsession_start(); //??session//?建随机?,并保存在session中for($i=0;$i<4;$i++){$_nmsg.=dechex(mt_r ...
- mysql - 查看Port
show global variables like 'port';
- oracle redo日志维护
环境 OS:Red Hat Linux As 5 DB:10.2.0.1 1.添加日志组 alter database add logfile group 4 ('/u01/app/oracle/or ...
- (三)Struts2 拦截器
所有的学习我们必须先搭建好Struts2的环境(1.导入对应的jar包,2.web.xml,3.struts.xml) 第一节:拦截器简介 (百度百科Struts2) Struts2 拦截器是在访问某 ...
- 第一章JSP基础语法
jsp页面元素构成 jsp页面组成部分有:指令,注释,静态内容,表达式,小脚本,声明. jsp指令 page指令:通常位于jsp页面的顶端,同一个页面可以有多个page指令 include指令:将一个 ...
- TCP与UDP网络编程总结(一)
(1):TCP网络编程 我们注意到服务端与客户端通信时是通过客户端的套接字相互通信的,那么服务端的套接字主要是干什么用的呢? TCP服务端设置监听套接字时 int listen(int sock,in ...
- 理解ThreadLocal背后的概念
介绍 我之前在任何场合都没有使用过thread local,因此没有注意到它,直到最近用到它的时候. 前提信息 线程可以理解为一个单独的进程,它有自己的调用栈.在java中每一个线程都有一个调用栈或者 ...
- (转)ASP.NET-关于Container dataitem 与 eval方法介绍
Container是一个数据容器,代表集合类或者dataview中的一行,而Container.dataitem代表该行的数据:所有的container 被存 放在是一个栈堆stack中,自动的将 ...