小编ben*_*ben的帖子

Java Concurrency in Practice - 示例14.12

// Not really how java.util.concurrent.Semaphore is implemented
@ThreadSafe
public class SemaphoreOnLock {
    private final Lock lock = new ReentrantLock();
    // CONDITION PREDICATE: permitsAvailable (permits > 0)
    private final Condition permitsAvailable = lock.newCondition();
    @GuardedBy("lock") private int permits;

    SemaphoreOnLock(int initialPermits) {
        lock.lock();
        try {
            permits = initialPermits;
        } finally {
            lock.unlock();
        }
    }

/* other code omitted.... */
Run Code Online (Sandbox Code Playgroud)

我有一个关于上面的示例的问题,该示例是从Java Concurrency中提取的实践清单14.12计算使用Lock实现的信号量.

我想知道为什么我们需要在构造函数中获取锁(如图所示调用lock.lock()).据我所知,构造函数是原子的(除了引用转义),因为没有其他线程可以获得引用,因此,半构造对象对其他线程不可见.因此,我们不需要构造函数的synchronized修饰符.此外,只要对象安全发布,我们也不需要担心内存可见性.

那么,为什么我们需要在构造函数中获取ReentrantLock对象?

java concurrency multithreading locking

15
推荐指数
1
解决办法
2423
查看次数

Java 并发 - 发布不可变对象(Java 并发实践)

在 Java Concurrency In Practice 中,作者表示

  1. 不可变对象可以通过任何机制发布
  2. 任何线程都可以安全地使用不可变对象,而无需额外的同步,即使不使用同步来发布它们。

是否意味着以下习语可以安全地发布不可变对象?

public static List<ImmutableObject> list = new ArrayList<ImmutableObject>();

// thread A invokes this method first
public static void methodA () {
    list.add(new ImmutableObject());
}

// thread B invokes this method later
public static ImmutableObject methodB () {
    return list.get(0);
}
Run Code Online (Sandbox Code Playgroud)

会有数据竞赛吗?(这意味着线程 B 可能无法看到线程 A 添加的列表中的不可变对象)

非常感谢。


更进一步,作者说如果Resource是不可变的,下面的代码是安全的。

@NotThreadSafe
public class UnsafeLazyInitialization {
    private static Resource resource;

    public static Resource getInstance() {
        if (resource == null)
            resource = new Resource();  // unsafe publication …
Run Code Online (Sandbox Code Playgroud)

java concurrency multithreading java-memory-model

3
推荐指数
1
解决办法
1371
查看次数