【问题标题】:Should I set a boolean field as volatile?我应该将布尔字段设置为易失性吗?
【发布时间】:2012-07-05 02:34:29
【问题描述】:

以下代码是线程安全的吗?我真的需要将dataReady 设置为volatile,尽管一个线程只有一次写入和多次读取(如下所示的while 循环)?

public class MyApplication extends Application
{
    /* a flag indicates if the data is fully retrieved from the database */
    private volatile boolean dataReady = false;

    @Override
    public void onCreate()
    {
        super.onCreate();

        new AsyncTask<Void, Void, Void>()
        {
            @Override
            protected Void doInBackground(Void... params)
            {
                // retrieve data from the database
                return null;
            }

            @Override
            protected void onPostExecute(Void result)
            {
                dataReady = true;
            }
        }.execute();
    }

    public boolean isDataReady()
    {
        return dataReady;
    }
}

在其他线程(不是主线程)上:

while(!getApplication().isDataReady()); // wait until the data is ready

【问题讨论】:

    标签: java android multithreading concurrency volatile


    【解决方案1】:

    将布尔值标记为volatile 保证了可见性,换句话说,它保证了所有线程都会看到它的当前值。由于您在不同的线程中进行写入和读取,因此您必须将布尔值标记为 volatile

    如果您不将其标记为volatile,那么您的主线程很有可能(但不是系统地)将dataReady 设置为true,而另一个线程将看到该标志为false 并继续循环。在更糟糕的情况下,它甚至可能变成无限循环。

    【讨论】:

      【解决方案2】:
      though there is only one write and multiple reads from one thread 
      

      当它是单线程时,正如您所说的一次写入并多次读取,那么我认为不需要 volatile,因为 volatile 反映了一个线程对数据所做的更改另一个,

      但是假设你有多个线程读写数据库,最好使写入方法/语句同步,并且对数据使用volatile , 是从数据库中检索出来的,所以可以给线程多个访问权限来读取数据。

      【讨论】:

      • 看起来他的读取在同一个线程中,而写入在单独的线程上,因为它在 AsyncTask 内?
      • 那么他可以在 write 方法上使用 synchronized,在要读取的数据上使用 volatile,将为其他线程提供良好的可见性。如果多个线程正在读取它...
      【解决方案3】:

      代码不一定是线程安全的。虽然我知道系统可以设计为确保只有一个线程创建 MyApplication 的实例然后调用 onCreate,但这并不意味着您提供的代码 sn-p 本身就是线程安全的。因此,dataReady 应该被标记为 volatile。

      如您所知,易失性意味着主内存中只有一个变量副本,而不是由线程缓存的副本。我认为这在这种情况下是最合适的。

      【讨论】:

        猜你喜欢
        • 2021-09-07
        • 2017-01-31
        • 1970-01-01
        • 2020-07-29
        • 2020-10-06
        • 1970-01-01
        • 2018-01-18
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多