简体   繁体   English

什么是线程上下文中的缓存?何时在Java中使用volatile关键字?

[英]what is cache in context of threads and when to use volatile keyword in Java?

My understanding is that Java allows threads to access shared variables. 我的理解是Java允许线程访问共享变量。 As a rule, to ensure that shared variables are consistently updated, a thread should ensure that it has exclusive use of such variables by obtaining a lock that enforces mutual exclusion for those shared variables. 通常,为了确保一致地更新共享变量,线程应通过获取对这些共享变量强制执行互斥的锁来确保其专有使用此类变量。 If a field is declared volatile, in that case the Java memory model ensures that all threads see a consistent value for the variable. 如果将字段声明为易失性,则在这种情况下,Java内存模型可确保所有线程看到的变量值均一致。

In case of program below , tickectsAvailable is a shared variable which is stored on heap and because thread1 and thread2, are created on same object " obj " , both thread1 and thread2 have access to obj 在下面的程序中, tickectsAvailable是一个共享变量,存储在堆上,并且因为thread1和thread2是在同一对象“ obj ”上创建的, 因此thread1和thread2都可以访问obj

I am trying to understanding when to make a variable volatile. 我试图了解何时使变量可变。 Correct use case would be here in this case making "tickectsAvailable" volatile. 在这种情况下,正确的用例将使“ tickectsAvailable”易失。 Is my understanding on volatile variables correct? 我对volatile变量的理解正确吗?

I read an article that says : Each thread may copy variables from main memory into a CPU cache while working on them, for performance reasons. 我读了一篇文章说:由于性能原因,每个线程在进行操作时可能会将变量从主内存复制到CPU缓存中。 If your computer contains more than one CPU, each thread may run on a different CPU. 如果您的计算机包含多个CPU,则每个线程可能在不同的CPU上运行。 That means, that each thread may copy the variables into the CPU cache of different CPUs 这意味着每个线程可以将变量复制到不同CPU的CPU缓存中

In this case, if i do not make "tickectsAvailable" volatile, there are changes that threads may read from CPU cache if i have multiple threads working of same object("obj") here in case of only more than one CPU? 在这种情况下,如果我不使“ tickectsAvailable”易失,那么如果我有多个线程在同一对象(“ obj”)上工作,并且只有一个以上的CPU,那么线程可能会从CPU缓存中读取更改?

Should Volatile variable be used only when your computer contains multiple CPU's? 仅当您的计算机包含多个CPU时才应使用Volatile变量吗? But if i have multiple threads on same obj and one cpu how is it going to behave? 但是,如果我在同一obj和一个cpu上有多个线程,它将如何表现?

class TicketBooking implements Runnable{
        int ticketsAvailable=1;

        public void run(){

               System.out.println("Waiting to book ticket for : "+Thread.currentThread().getName());
               synchronized (this) {
                      if(ticketsAvailable>0){
                            System.out.println("Booking ticket for : "+Thread.currentThread().getName());

                            //Let's say system takes some time in booking ticket (here we have taken 1 second time)
                            try{
                                   Thread.sleep(1000); 
                            }catch(Exception e){}

                            ticketsAvailable--;
                            System.out.println("Ticket BOOKED for : "+ Thread.currentThread().getName());
                            System.out.println("currently ticketsAvailable = "+ticketsAvailable);
                      }
                      else{
                            System.out.println("Ticket NOT BOOKED for : "+ 
                                      Thread.currentThread().getName());
                      }

               }//End synchronization block


        }

    }

    /** Copyright (c), AnkitMittal JavaMadeSoEasy.com */
    public class MyClass {
        public static void main(String args[])
        {
               TicketBooking obj=new TicketBooking();

               Thread thread1=new Thread(obj,"Passenger1 Thread");
               Thread thread2=new Thread(obj,"Passenger2 Thread");

               thread1.start();
               thread2.start();

        }

    }

    /*OUTPUT

    Waiting to book ticket for : Passenger2 Thread
    Waiting to book ticket for : Passenger1 Thread
    Booking ticket for : Passenger2 Thread
    Ticket BOOKED for : Passenger2 Thread
    currently ticketsAvailable = 0
    Ticket NOT BOOKED for : Passenger1 Thread

    */

Volatile variable guarantees happen before relation . 易变变量担保在关系发生之前发生 If only one thread is writing and all other threads are reading a variable, in that case volatile variables ensure thread safety. 如果只有一个线程在写,而所有其他线程正在读一个变量,那么在这种情况下,易失性变量可确保线程安全。 In other scenarios you have to use other synchronization mechanisms as per your need. 在其他情况下,您必须根据需要使用其他同步机制。

Should Volatile variable be used only when your computer contains multiple CPU's? 仅当您的计算机包含多个CPU时才应使用Volatile变量吗? But if i have multiple threads on same obj and one cpu how is it going to behave? 但是,如果我在同一obj和一个cpu上有多个线程,它将如何表现?

Operating system scheduler allocate CPU for every thread. 操作系统调度程序为每个线程分配CPU。 Every core can process one or more threads depends on hardware capability. 每个内核可以处理一个或多个线程,这取决于硬件功能。 Volatile variables is an abstraction within language, and it does not have any direct correlation with hardware capabilities. 易变变量是语言中的一种抽象,它与硬件功能没有任何直接关系。

Should Volatile variable be used only when your computer contains multiple CPU's? 仅当您的计算机包含多个CPU时才应使用Volatile变量吗?

Unless you are writing code for an embedded system , then optimizing your code for a specific hardware platform probably is a waste of your time. 除非您正在为嵌入式系统编写代码,否则针对特定硬件平台优化代码可能会浪费您的时间。 It could even be a costly mistake in the long run. 从长远来看,这甚至可能是代价高昂的错误。

If you are writing Java code, then it's pretty likely that you are writing a service, or a web app, or a mobile app, or a desktop app. 如果您正在编写Java代码,则很可能是在编写服务,Web应用程序,移动应用程序或台式机应用程序。 If you are writing any of those things, then your target should be the the generic Java platform or maybe, the Java platform and some particular SDK or framework. 如果您正在编写任何这些东西,那么您的目标应该是通用Java平台,或者Java平台和某些特定的SDK或框架。 Do yourself a favor and don't worry about the make and model of any computer or cell phone. 帮自己一个忙,不要担心任何计算机或手机的品牌和型号。

If a field is declared volatile, ... Java ... ensures that all threads see a consistent value for the variable 如果将某个字段声明为volatile,则... Java ...确保所有线程看到的变量值均一致

Any time you use the word, "consistent," you should ask yourself, "consistent with what? " 每当您使用“一致”一词时,都应该问自己“与什么一致”

If you mark a single variable as volatile , then all threads will see the value of the variable to be consistent with itself. 如果将单个变量标记为volatile ,则所有线程都将看到该变量的值与其自身一致。 That is, if you have a double d=0.0; 也就是说,如果您有一个double d=0.0;double d=0.0; , and thread A sets d=1.0; ,并且线程A设置d=1.0; , and thread B calls system.out.println(d); ,并且线程B调用system.out.println(d); at approximately the same time, then thread B is guaranteed to print either 0.0 or 1.0 . 在大约同一时间,然后保证线程B打印0.01.0 It will never print any other value. 它永远不会打印任何其他值。

Perhaps more significantly, if a volatile variable is updated many times, then all threads will agree upon one consistent order in which the updates happened. 也许更重要的是,如果易失性变量被多次更新,则所有线程将一致同意更新发生的一致顺序。

But, if you want several variables to be consistent with each other, then you should be protecting that group of variables with synchronized blocks or with a java.util.concurrent.locks.ReentrantLock object, and forget about volatile. 但是,如果您希望多个变量彼此一致,则应该使用synchronized块或java.util.concurrent.locks.ReentrantLock对象保护该组变量,而不必注意volatile.

Each thread may copy variables from main memory into a CPU cache... 每个线程都可以将变量从主内存复制到CPU缓存中。

There is no "cache" in Java. Java中没有“缓存”。 Java has its memory model . Java有其内存模型 CPU caches are the hidden reason behind the memory model. CPU缓存是内存模型背后的隐藏原因。 If you are implementing a JVM for some particular computer platform, then, hopefully, the Java memory model gives you some freedom to exploit the platform's cache system to your advantage. 如果您要为某些特定的计算机平台实现JVM,那么希望Java内存模型为您提供一定的自由度,可以利用该平台的缓存系统来发挥自己的优势。

If you are writing code for the Java platform, then you should worry first about the Java memory model, and whether or not your program will behave correctly in the face of it. 如果您正在为Java平台编写代码,则应首先担心Java内存模型,以及程序在面对它时是否会正确运行。 Learning about cache memory systems is an extra-curricular activity that may help you to feel better about your understanding of why Java is the way it is. 了解缓存系统是一项课外活动,可以帮助您更好地理解Java的用途。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM