Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/232.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 我应该将布尔字段设置为volatile吗?_Java_Android_Multithreading_Concurrency_Volatile - Fatal编程技术网

Java 我应该将布尔字段设置为volatile吗?

Java 我应该将布尔字段设置为volatile吗?,java,android,multithreading,concurrency,volatile,Java,Android,Multithreading,Concurrency,Volatile,以下代码是线程安全的吗?我真的需要将dataReady设置为volatile,尽管一个线程只有一次写入和多次读取(while循环如下所示) 如果是单线程,如您所述,写一次,读多次,那么我认为不需要volatile,因为volatile反映了一个线程对另一个线程对数据所做的更改 但是,假设您有多个线程读取和写入数据库,最好将写入方法/语句设置为同步,并对从数据库检索的数据使用volatile,因此,可以从线程获得多个访问权限来读取数据。代码不一定是线程安全的。虽然我知道系统的设计可以确保只有一个线

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

如果是单线程,如您所述,写一次,读多次,那么我认为不需要volatile,因为volatile反映了一个线程对另一个线程对数据所做的更改


但是,假设您有多个线程读取和写入数据库,最好将写入方法/语句设置为同步,并对从数据库检索的数据使用volatile,因此,可以从线程获得多个访问权限来读取数据。

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


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

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


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

看起来他的读取在同一个线程中,而写入在一个单独的线程上,因为它在AsyncTask中?那么他可以在写入方法上使用synchronized,在要读取的数据上使用volatile,这将为其他线程提供良好的可见性。如果多个线程正在读取它。。。
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
though there is only one write and multiple reads from one thread