java并发实践1 博客分类: java并发 javaconcurrency
程序员文章站
2024-02-13 18:06:22
...
1.没有属性的对象是“线程安全”的。Stateless objects are always thread-safe.
2.原子性.Atomicity
《Concurrency in practice》里这样说,
这段的大意是:
3.Race Condition in Lazy Initialization. Don't Do this.
4.Servlet that Counts Requests Using AtomicLong.
2013-6-26 增加:
清单 4.3. 使用private的锁还保证state
看到这里,state可能大家会不知道是什么,其实就是成员变量,就是java类的全局变量。
2.原子性.Atomicity
@NotThreadSafe public class UnsafeCountingFactorizer implements Servlet { private long count = 0; public long getCount() { return count; } public void service(ServletRequest req, ServletResponse resp) { BigInteger i = extractFromRequest(req); BigInteger[] factors = factor(i); ++count; encodeIntoResponse(resp, factors); } }
《Concurrency in practice》里这样说,
引用
Unfortunately, UnsafeCountingFactorizer is not thread-safe, even though it would work just fine in a single-threaded environment. Just like UnsafeSequence on page 6, it is susceptible to lost updates. While the increment operation, ++count, may look like a single action because of its compact syntax, it is not atomic, which means that it does not execute as a single, indivisible operation. Instead, it is a shorthand for a sequence of three discrete operations: fetch the current value, add one to it, and write the new value back. This is an example of a read-modify-write operation, in which the resulting state is derived from the previous state.
这段的大意是:
引用
不幸的,UnsafeCountingFactorizer不是线程安全的,尽管它能在单线程环境中很好的工作。就像第6页的UnsafeSequence 它是容易受“丢失更新”的影响的。 自增运算,++count,大概因为它语法简单看起来很像是单步执行的,但它并非原子的,这意味着它不能简单的执行,不可见的操作。反而,它是一个一系列操作的简写:取当前值,值增加1,写回新值。这是一个读-改-写的操作,在那里结果状态是由前一个状态决定。
3.Race Condition in Lazy Initialization. Don't Do this.
@NotThreadSafe public class LazyInitRace { private ExpensiveObject instance = null; public ExpensiveObject getInstance() { if (instance == null) instance = new ExpensiveObject(); return instance; } }
引用
LazyInitRace has race conditions that can undermine its correctness. Say that threads A and B execute getInstance at the same time. A sees that instance is null, and instantiates a new ExpensiveObject. B also checks if instance is null. Whether instance is null at this point depends unpredictably on timing, including the vagaries of scheduling and how long A takes to instantiate the ExpensiveObject and set the instance field. If instance is null when B examines it, the two callers to getInstance may receive two different results, even though getInstance is always supposed to return the same instance.
4.Servlet that Counts Requests Using AtomicLong.
@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); } }
引用
The java.util.concurrent.atomic package contains atomic variable classes for effecting atomic state transitions on numbers and object references. By replacing the long counter with an AtomicLong, we ensure that all actions that access the counter state are atomic. [5] Because the state of the servlet is the state of the counter and the counter is thread-safe, our servlet is once again thread-safe.
2013-6-26 增加:
清单 4.3. 使用private的锁还保证state
public class PrivateLock{ private final Object myLock = new Object(); Object resource; public void operate(){ synchronized(myLock) { // 这里来改变resource } } }
看到这里,state可能大家会不知道是什么,其实就是成员变量,就是java类的全局变量。
推荐阅读
-
java并发实践1 博客分类: java并发 javaconcurrency
-
线程同步之wait() 博客分类: java并发 javathread
-
深入理解Java内存模型(二)——重排序 博客分类: java并发
-
线程同步之wait() 博客分类: java并发 javathread
-
java并发实践1 博客分类: java并发 javaconcurrency
-
Java并发实战-私有构造函数捕获 博客分类: JAVA Java构造函数捕获
-
Java并发编程-客户端加锁机制 博客分类: JAVA 客户端加锁机制
-
Java并发编程:synchronized 博客分类: Java 多线程 synchonized
-
Java并发编程:synchronized 博客分类: Java 多线程 synchonized
-
记我的第一次spring aop项目实践 博客分类: Java aopspringaspectjspring aop日志记录