- 浏览: 874765 次
- 性别:
- 来自: 北京
博客专栏
-
Java Concurre...
浏览量:97516
文章分类
最新评论
-
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 2664[本文是我对Java Concurrency In Pract ... -
内置锁和显式锁的区别--JCIP C13读书笔记
2012-04-11 10:17 5781[本文是我对Java Concurrenc ... -
改善并发程序的可扩展性--JCIP C11读书笔记
2012-04-10 14:40 2512[本文是我对Java Concurrency In Pract ... -
如何避免死锁--JCIPC10读书笔记
2012-04-10 10:08 3151[本文是我对Java Concurrency In Pract ... -
task与execution--JCIPC08读书笔记
2012-04-09 10:34 2401[本文是我对Java Concurrency In Pract ... -
配置ThreadPoolExecutor
2012-04-09 10:34 6233[本文是我对Java Concurrency In Pract ... -
停止基于线程的Service--JCIP7.2读书笔记
2012-04-06 10:28 2335[本文是我对Java Concurrency In Pract ... -
处理不可中断的阻塞-JCIP7.1读书笔记
2012-04-06 10:23 5703[本文是我对Java Concurrenc ... -
处理InterruptedException异常--JCIP7.1读书笔记
2012-04-05 14:08 6127[本文是我对Java Concurrency In Pract ... -
中断线程--JCIP7.1读书笔记
2012-04-05 14:03 2613[本文是我对Java Concurrency In Pract ... -
改善并发性能--JCIP6.3读书笔记
2012-04-02 11:51 2573[本文是我对Java Concurrency In Pr ... -
Executor--JCIP C06读书笔记
2012-04-02 09:28 2864[本文是我对Java Concurrency In Pract ... -
设计高效的线程安全的缓存--JCIP5.6读书笔记
2012-04-01 22:49 5872[本文是我对Java Concurrency In Pract ... -
synchronizer--JCIP5.5读书笔记
2012-04-01 22:44 2347[本文是我对Java Concurrency In Pract ... -
使用BlockingQueue构建生产者消费者模式--JCIP5.3读书笔记
2012-03-31 17:32 4640[本文是我对Java Concurrency In Pract ... -
ConcurrentHashMap和CopyOnWriteArrayList--Java Concurrency In Practice C05读书笔记
2012-03-31 11:27 4043[本文是我对Java Concurrenc ... -
线程安全的集合类--Java Concurrency In Practice C05读书笔记
2012-03-28 18:26 14247[本文是我对Java Concurrency In Pract ... -
利用对象限制和委托构建线程安全的类--Java Concurrency In Practice C04读书笔记
2012-03-27 18:23 3829[本文是我对Java Concurrency In Pract ... -
变量可见性和volatile, this逃逸, 不可变对象, 以及安全公开--Java Concurrency In Practice C03读书笔记
2012-03-26 21:55 12585[本文是我对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删除 本资源转载自网络,如有侵权,请联系上传者...
<<java并行编程>>英文版chm格式,英文名称<Java Concurrency in Practice>,一直想买这本书,但总是缺货,找到了电子版,分享给大家。 Java Concurrency in Practice By Brian Goetz, Tim Peierls, Joshua Bloch,...
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 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.