如何使 volatile count++ 操作成为线程安全的 [英] how does the volatile count++ operation be made thread safe

查看:53
本文介绍了如何使 volatile count++ 操作成为线程安全的的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在通过 JCIP,作者说..

I have been going through JCIP and there the author says..

线程限制的一种特殊情况适用于 volatile 变量.只要确保 volatile 变量仅从单个线程写入,就可以安全地对共享的 volatile 变量执行读-修改-写操作

A special case of thread confinement applies to volatile variables. It is safe to perform read-modify-write operations on shared volatile variables as long as you ensure that the volatile variable is only written from a single thread

例如 count++ 被认为是一个复合操作(读取值,加一,更新值)并且将 count 声明为 volatile 不会使这个操作原子化,所以这里不保证线程安全!我对吗 ??但是这里作者说,如果我们确保 volatile 变量仅从单个线程写入,我们就可以修复它.我不明白这一点.请提供说明.

For instance count++ is considered a compound operation (reading the value,adding one to it,and updating the value) and declaring count as volatile does not make this operation atomic, so thread safety is not guaranteed here !! Am i right ?? But here the author says we can fix it if we ensure that the volatile variable is only written from a single thread. I am failing to understand this. Please provide an illustration.

推荐答案

一个典型的用例可能如下所示:

A typical use case could look something like this:

public class Foo implements Runnable {
    private volatile int itemsProcessed;

    public int getItemsProcessed() { return itemsProcessed; }

    @Override
    public void run() {
        while (true) { //this is just an example so we don't care about stopping
            processItem(); //process a single item
            itemsProcessed++;
        }
    }
}

现在其他人可以在没有额外同步的情况下查询您线程的进度,但只允许线程本身更新它.对于其他所有人,该字段是只读的.

Now others can query your thread's progress without extra synchronization but only the thread itself is allowed to update it. For everyone else the field is read-only.

如果没有 volatile,其他线程可能根本看不到 itemProcessed 的任何变化,甚至可能会以古怪的顺序看到它们,有时增加,有时减少.

Without volatile other threads may not see any change to itemProcessed at all, or may even see them in a wacky order, sometimes increasing, sometimes decreasing.

多线程可以在没有任何额外同步的情况下写入 volatile 变量的唯一情况是写入是幂等的(即多次写入具有相同的效果作为一个).这可以在用于停止线程的模式中看到:

The only time multiple threads are okay to write to a volatile variable without any extra synchronization is if the writes are idempotent (that is, multiple writes have the same effect as a single one). This can be seen in this pattern used to stop a thread:

public class Foo implements Runnable {
    private volatile boolean stopped = false;

    public void stopProcessing() {
        stopped = true;
    }

    public int getItemsProcessed() { return itemsProcessed; }

    @Override
    public void run() {
        while (!stopped) { 
            processItem(); //process a single item
        }
    }
}

这里其他线程唯一能做的就是将 stopped 设置为 true.不管有多少人这样做,按什么顺序,结果总是一样的.

Here the only thing other threads can do is set stopped to true. It doesn't matter how many of them do it and in what order, the result will always be the same.

这篇关于如何使 volatile count++ 操作成为线程安全的的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆