- 浏览: 874072 次
- 性别:
- 来自: 北京
博客专栏
-
Java Concurre...
浏览量:97244
文章分类
最新评论
-
guo_guo_guo:
mark
Zookeeper 安装和配置 -
solrer:
xunux 写道windows下,dataDir目录若是用需要 ...
Zookeeper 安装和配置 -
kevlearnjava:
你好 我是按照你的伪集群进行配置的 然后启动第二个和第三个 ...
Zookeeper 安装和配置 -
筑浪小子:
博主应该把vector设定为全局变量,更加清晰一些
线程安全的集合类--Java Concurrency In Practice C05读书笔记 -
tt5753:
jps16437 QuorumPeerMain16663 Zo ...
Zookeeper 安装和配置
[本文是我对Java Concurrency In Practice第二章的归纳和总结, 转载请注明作者和出处, 如有谬误, 欢迎在评论中指正. ]
多线程环境下,无需调用方进行任何同步处理也能保证正确性的类是线程安全的类
无状态的对象是线程安全的。无状态是指没有成员变量。由于方法的局部变量都是在线程私有的栈中分配的,因此在一个线程中调用无状态对象的方法,不会影响到其他线程。
race condition: 正确性依赖于事件发生的相对时间。
check-and-act是race condition中的一种,指的是基于check的结果进行操作。由于check和act并非是原子的,进行act时check的结果可能已经无效,那么基于check所进行的act就可能带来问题。
见如下的lazy单例类:
public class LazyInitRace { private static ExpensiveObject instance = null; public static ExpensiveObject getInstance() { // if语句是一个check-and-act操作 if (instance == null) { instance = new ExpensiveObject(); } return instance; } }这是一个check-and-act的典型例子:首先判断instance是否为null,如果是就创建ExpensiveObject对象,否则直接返回instance。但是判断和创建并非原子操作,假设线程1判断出instance为null,要是另一个线程紧接着创建了ExpensiveObject对象,那么线程1的判断就失效了,基于判断结果所进行的创建操作就会导致程序中存在多个ExpensiveObject对象--这违背了单例模式的初衷。
Read‐modify‐write也是race condition中的一种,指的是读取某个变量的值,修改后写回。这显然不是一个原子操作,如果B线程在A线程read之后write之前修改了变量的值,那么A线程read的结果就失效了,基于read所做的modify就可能带来问题。
见如下的servlet:
public class CountingFactorizer implements Servlet { private final long count = 0; public void service(ServletRequest req, ServletResponse resp) { BigInteger i = extractFromRequest(req); BigInteger[] factors = factor(i); // // 自增语句是一个Read‐modify‐write操作 count++; encodeIntoResponse(resp, factors); } }
使用java提供的同步机制,将check-and-act或者Read‐modify‐write转换为原子操作,则可以避免race condition造成的错误。
使用同步机制改进LazyInitRace和CountingFactorizer类,使之成为线程安全的类:
public class LazyInitRace { private static ExpensiveObject instance = null; public static ExpensiveObject getInstance() { // 使用synchronized将check-and-act操作转换为原子操作 if (instance == null) { synchronized (LazyInitRace.class) { if (instance == null) { instance = new ExpensiveObject(); } } } return instance; } } public class CountingFactorizer implements Servlet { private final AtomicLong count = new AtomicLong(0); public void service(ServletRequest req, ServletResponse resp) { BigInteger i = extractFromRequest(req); BigInteger[] factors = factor(i); // 使用long对应的原子类AtomicLong,将Read‐modify‐write操作转换为原子操作 count.incrementAndGet(); encodeIntoResponse(resp, factors); } }
对于只有一个成员变量的对象,成员的状态就是对象的状态。如果涉及到该成员的操作都是原子的,那么该类就是一个线程安全的类。比如以上的LazyInitRace类,其只有一个成员变量instance,且涉及instance的操作是原子的,因此LazyInitRace类是一个线程安全的类。
是否可以类推出,只要类的每一个成员变量的操作都是原子的,类就是线程安全的?不行。
因为每一个成员的操作都是原子的,不能保证所有涉及到成员的操作整体上是原子的。例如:
public class UnsafeCachingFactorizer implements Servlet { private final AtomicReference<BigInteger> lastNumber = new AtomicReference<BigInteger>(); private final AtomicReference<BigInteger[]> lastFactors = new AtomicReference<BigInteger[]>(); public void service(ServletRequest req, ServletResponse resp) { BigInteger i = extractFromRequest(req); // 优先使用缓存 if (i.equals(lastNumber.get())) encodeIntoResponse(resp, lastFactors.get() ); else { BigInteger[] factors = factor(i); // 将最后一次的计算结果缓存起来 lastNumber.set(i); lastFactors.set(factors); encodeIntoResponse(resp, factors); } } }UnsafeCachingFactorizer类的2个成员lastNumber和lastFactors的set()和get()方法是原子的,但是该类不是线程安全的。因为从整体上看,2次写入和2次读取都不是同时进行的,UnsafeCachingFactorizer类仍然存在race condition.
java的synchronized机制使用的锁是可重入锁,即同一个线程可以多次申请持有同一把锁而不会引起死锁。假设A线程持有lock,那么如果B线程申请lock锁,B线程就会被阻塞。但是如果A线程再次申请已经持有的lock锁,该申请将获得通过,这就是所谓的同一线程可多次获取同一把锁。作为锁的对象,不仅需要标识锁的所有者,也需要标识所有者持有的计数。如果所有者线程刚刚申请到锁,则计数器的值为1,每重新获取一次,计数器的值加1,每退出一个同步代码块,计数器的值减1. 当计数器的值减为0时,所有者线程才释放锁。可重入锁的设计是为了防止因申请已持有的锁而造成死锁,例如:
public class Widget { public synchronized void doSomething() { ... } } public class LoggingWidget extends Widget { public synchronized void doSomething() { System.out.println(toString() + ": calling doSomething"); super.doSomething(); } }如果java中的锁不是可重入的,那么调用LoggingWidget对象的doSomething方法就会导致死锁。
评论
子类的doSomething()覆盖了父类的doSomething(),当子类的doSomething()执行时,synchronized 锁定了子类对象,然后再执行super.doSomething()时,父类的doSomething()的synchronized 需要锁定父类对象吧?
是不是synchronized 不区分子类对象 和 父类的对象?
这样,当锁是可重入的时,在子类LoggingWidget synchronized 锁定了一个对象,再执行super.doSomething()时,又需要锁定一个对象,这两个对象(一个是子类型,一个是父类型)对synchronized 而言,没有区别?
锁定的是同一个对象呀!
子类继承了父类的方法,然后又被重写了,所以从父类继承的方法变成隐式的不会显现,非要调用必须用super.来触发
子类的doSomething()覆盖了父类的doSomething(),当子类的doSomething()执行时,synchronized 锁定了子类对象,然后再执行super.doSomething()时,父类的doSomething()的synchronized 需要锁定父类对象吧?
是不是synchronized 不区分子类对象 和 父类的对象?
这样,当锁是可重入的时,在子类LoggingWidget synchronized 锁定了一个对象,再执行super.doSomething()时,又需要锁定一个对象,这两个对象(一个是子类型,一个是父类型)对synchronized 而言,没有区别?
发表评论
-
状态依赖的类--JCIP C14.1读书笔记
2012-04-11 10:24 2659[本文是我对Java Concurrency In Pract ... -
内置锁和显式锁的区别--JCIP C13读书笔记
2012-04-11 10:17 5771[本文是我对Java Concurrenc ... -
改善并发程序的可扩展性--JCIP C11读书笔记
2012-04-10 14:40 2488[本文是我对Java Concurrency In Pract ... -
如何避免死锁--JCIPC10读书笔记
2012-04-10 10:08 3135[本文是我对Java Concurrency In Pract ... -
task与execution--JCIPC08读书笔记
2012-04-09 10:34 2393[本文是我对Java Concurrency In Pract ... -
配置ThreadPoolExecutor
2012-04-09 10:34 6217[本文是我对Java Concurrency In Pract ... -
停止基于线程的Service--JCIP7.2读书笔记
2012-04-06 10:28 2330[本文是我对Java Concurrency In Pract ... -
处理不可中断的阻塞-JCIP7.1读书笔记
2012-04-06 10:23 5696[本文是我对Java Concurrenc ... -
处理InterruptedException异常--JCIP7.1读书笔记
2012-04-05 14:08 6116[本文是我对Java Concurrency In Pract ... -
中断线程--JCIP7.1读书笔记
2012-04-05 14:03 2591[本文是我对Java Concurrency In Pract ... -
改善并发性能--JCIP6.3读书笔记
2012-04-02 11:51 2555[本文是我对Java Concurrency In Pr ... -
Executor--JCIP C06读书笔记
2012-04-02 09:28 2858[本文是我对Java Concurrency In Pract ... -
设计高效的线程安全的缓存--JCIP5.6读书笔记
2012-04-01 22:49 5846[本文是我对Java Concurrency In Pract ... -
synchronizer--JCIP5.5读书笔记
2012-04-01 22:44 2342[本文是我对Java Concurrency In Pract ... -
使用BlockingQueue构建生产者消费者模式--JCIP5.3读书笔记
2012-03-31 17:32 4602[本文是我对Java Concurrency In Pract ... -
ConcurrentHashMap和CopyOnWriteArrayList--Java Concurrency In Practice C05读书笔记
2012-03-31 11:27 4036[本文是我对Java Concurrenc ... -
线程安全的集合类--Java Concurrency In Practice C05读书笔记
2012-03-28 18:26 14237[本文是我对Java Concurrency In Pract ... -
利用对象限制和委托构建线程安全的类--Java Concurrency In Practice C04读书笔记
2012-03-27 18:23 3824[本文是我对Java Concurrency In Pract ... -
变量可见性和volatile, this逃逸, 不可变对象, 以及安全公开--Java Concurrency In Practice C03读书笔记
2012-03-26 21:55 12558[本文是我对Java Concurrency In Pract ... -
变量可见性和volatile, this逃逸, 不可变对象, 以及安全公开--Java Concurrency In Practice C02读书笔记
2012-03-26 21:53 2[本文是我对Java Concurrency In Pract ...
相关推荐
Java Concurrency in Practice 英文无水印pdf pdf所有页面使用FoxitReader和PDF-XChangeViewer测试都可以打开 本资源转载自网络,如有侵权,请联系上传者或csdn删除 本资源转载自网络,如有侵权,请联系上传者...
Using the concurrency building blocks in java.util.concurrent Performance optimization dos and don'ts Testing concurrent programs Advanced topics such as atomic variables, nonblocking algorithms, ...
《Java并发编程实践》是Java开发者必读的经典之作,由Brian Goetz等多位专家共同撰写。这本书深入浅出地探讨了Java平台上的并发问题,帮助读者理解和掌握如何编写高效、可靠且可维护的多线程应用程序。以下是该书...
Java Concurrency in practice
Java Concurrency in Practice JAVA并发编程实践中文版(全)第二部分
<<java并行编程>>英文版chm格式,英文名称<Java Concurrency in Practice>,一直想买这本书,但总是缺货,找到了电子版,分享给大家。 Java Concurrency in Practice By Brian Goetz, Tim Peierls, Joshua Bloch,...
《Java Concurrency in Practice》是Java并发编程领域的一本经典著作,由Brian Goetz、Tim Peierls、Joshua Bloch、Joseph Bowles和Doug Lea等专家共同编写。这本书深入探讨了Java平台上的多线程和并发编程,旨在...
java concurrency in practice 经典的多线程编程书籍,英文版
这里的"java_concurrency_in_practice_source"源代码正是书中实例的实现,它涵盖了Java多线程编程中的关键概念和技术。 1. **线程基础**:Java中创建线程有两种方式,一是通过`Thread`类的子类,二是实现`Runnable`...
本笔记将深入探讨《Java Concurrency In Practice》这本书中的核心概念,结合Guava库的实际使用案例,帮助读者理解并掌握Java并发编程的精髓。 首先,我们来了解Java并发的基础知识。Java提供了丰富的并发工具类,...
首先,"Java Concurrency in Practice"是Java并发编程的经典之作,由Brian Goetz、Tim Peierls、Joshua Bloch、David Holmes和Doug Lea合著。这本书提供了一套实用的指导原则、设计模式和最佳实践,帮助Java开发者...
《Java Concurrency In Practice》是一本关于Java并发编程的经典著作,由Brian Göetz、Tim Peierls、Joshua Bloch、Joseph Bowbeer、David Holmes和Doug Lea共同编写。本书深入探讨了Java平台上的多线程编程技巧,...
java_concurrency_in_practice.pdf jcip-examples-src.jar jcip-annotations-src.jar 英文版是高清晰的,实战和实践都是同一帮人对英文版书的翻译,网传实战的翻译质量更好,实战是2012年出版的,应该是对前一版实践...
- **书名**:《Java并发实践》(Java Concurrency in Practice) - **作者**:Brian Goetz, Tim Peierls, Joshua Bloch, Joseph Bowbeer, David Holmes, Doug Lea - **出版社**:Addison Wesley Professional - **...
这本书很出名吧,大家都知道吧,我靠,20个字的描述咋这么累啊。
If you are a java developer, you should read this book. It will bring a lot benifit to you.