欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

java并发实践1 博客分类: java并发 javaconcurrency 

程序员文章站 2024-02-13 18:06:22
...
1.没有属性的对象是“线程安全”的。Stateless objects are always thread-safe.
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 concurrency