相关疑难解决方法(0)

atomic/volatile/synchronized有什么区别?

原子/易失性/同步如何在内部工作?

以下代码块之间有什么区别?

代码1

private int counter;

public int getNextUniqueIndex() {
    return counter++; 
}
Run Code Online (Sandbox Code Playgroud)

代码2

private AtomicInteger counter;

public int getNextUniqueIndex() {
    return counter.getAndIncrement();
}
Run Code Online (Sandbox Code Playgroud)

代码3

private volatile int counter;

public int getNextUniqueIndex() {
    return counter++; 
}
Run Code Online (Sandbox Code Playgroud)

是否volatile以下列方式工作?是

volatile int i = 0;
void incIBy5() {
    i += 5;
}
Run Code Online (Sandbox Code Playgroud)

相当于

Integer i = 5;
void incIBy5() {
    int temp;
    synchronized(i) { temp = i }
    synchronized(i) { i = temp + 5 }
}
Run Code Online (Sandbox Code Playgroud)

我认为两个线程不能同时进入同步块...我是对的吗?如果这是真的那么如何atomic.incrementAndGet()工作没有synchronized …

java multithreading synchronization atomic volatile

282
推荐指数
4
解决办法
13万
查看次数

Java:将所有字段设为final还是volatile?

如果我有一个在线程之间共享的对象,在我看来每个字段应该是final或者volatile,具有以下推理:

  • 如果应该更改字段(指向另一个对象,更新原始值),那么该字段应该是volatile所有其他线程对新值进行操作.仅仅访问所述字段的方法的同步是不够的,因为它们可能返回缓存的值.

  • 如果该领域永远不会改变,那就去做吧final.

但是,我找不到任何关于此的内容,所以我想知道这个逻辑是否有缺陷还是太明显?

当然编辑而不是易失性可能使用final AtomicReference或类似.

编辑,例如,请参阅get getter方法是Java中volatile的替代方法吗?

编辑以避免混淆:这个问题是关于缓存失效!如果两个线程对同一个对象进行操作,则可以缓存对象的字段(每个线程),如果它们未声明为volatile.如何保证缓存无效?

最后的编辑感谢@Peter Lawrey,他指出了JLS§17(Java内存模型).据我所知,它表明同步在操作之间建立了先发生关系,因此如果那些更新"发生在之前",则线程会看到来自另一个线程的更新,例如,如果非易失性字段的getter和setter是synchronized.

java multithreading final volatile

23
推荐指数
2
解决办法
2071
查看次数

出于稀薄的空气安全

Java Concurrency in Practice解释了这个概念:

当一个线程在没有同步的情况下读取一个变量时,它可能会看到一个陈旧的值,但至少它会看到某个线程实际放置的值而不是某个随机值.这种安全保证称为超薄空气安全.

这种安全性是否很弱,因为它可能包含陈旧价值?

也许这个片段,at least it sees a value that was actually placed there by some thread than some random value是因为本书的上一个主题是JVM重新命令变量语句的可能性sharing variables without synchronization

示例:根据重新排序:42或0可以打印出来.

public class NoVisibility {
    private static boolean ready;
    private static int number;

    private static class ReaderThread extends Thread {
        public void run() {
            while(!ready)  
                Thread.yield();
            System.out.println(number);
            }
        }

    public static void main(String[] args) {
        new ReaderThread().start();
        number = 42;
        ready = true;
    }
}
Run Code Online (Sandbox Code Playgroud)

编辑 - 删除"请评论"评论.

java multithreading

2
推荐指数
2
解决办法
1689
查看次数

标签 统计

java ×3

multithreading ×3

volatile ×2

atomic ×1

final ×1

synchronization ×1