亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

什么是線程上下文中的緩存以及何時在 Java 中使用 volatile 關鍵字?

什么是線程上下文中的緩存以及何時在 Java 中使用 volatile 關鍵字?

慕容森 2021-07-09 18:11:48
我的理解是 Java 允許線程訪問共享變量。通常,為了確保共享變量持續更新,線程應該通過獲取對這些共享變量強制互斥的鎖來確保它獨占使用這些變量。如果一個字段被聲明為 volatile,在這種情況下,Java 內存模型確保所有線程看到變量的一致值。在下面的程序中,ticectsAvailable是一個存儲在堆上的共享變量,因為 thread1 和 thread2 是在同一個對象“ obj ”上創建的,所以 thread1 和 thread2 都可以訪問 obj我試圖了解何時使變量變得易變。在這種情況下,正確的用例將在這里使“ticketsAvailable”變得不穩定。我對 volatile 變量的理解正確嗎?我讀過一篇文章說:出于性能原因,每個線程在處理變量時可能會將變量從主內存復制到 CPU 緩存中。如果您的計算機包含多個 CPU,則每個線程可能運行在不同的 CPU 上。這意味著,每個線程都可以將變量復制到不同 CPU 的 CPU 緩存中在這種情況下,如果我不使“tickectsAvailable”不穩定,如果我有多個線程處理同一對象(“obj”),并且只有一個以上的 CPU,那么線程可能會從 CPU 緩存中讀取更改?僅當您的計算機包含多個 CPU 時才應使用易失性變量嗎?但是,如果我在同一個 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        }    }
查看完整描述

2 回答

?
qq_花開花謝_0

TA貢獻1835條經驗 獲得超7個贊

僅當您的計算機包含多個 CPU 時才應使用易失性變量嗎?

除非您正在為嵌入式系統編寫代碼,否則針對特定硬件平臺優化您的代碼可能是在浪費您的時間。從長遠來看,這甚至可能是一個代價高昂的錯誤。

如果您正在編寫 Java 代碼,那么您很可能正在編寫服務、Web 應用程序、移動應用程序或桌面應用程序。如果您正在編寫任何這些內容,那么您的目標應該是通用 Java 平臺,或者 Java 平臺和某些特定的 SDK 或框架。幫自己一個忙,不要擔心任何電腦或手機的品牌和型號。

如果一個字段被聲明為 volatile,... Java ... 確保所有線程看到變量的一致值

每當你使用“一致”這個詞時,你應該問自己,“與什么一致? ”

如果將單個變量標記為volatile,那么所有線程都會看到該變量的值與自身一致。也就是說,如果您有一個double d=0.0;,并且線程 A 設置了d=1.0;,并且線程 Bsystem.out.println(d);大約在同一時間調用,則線程 B 保證打印0.01.0。它永遠不會打印任何其他值。

也許更重要的是,如果一個 volatile 變量被更新多次,那么所有線程將就更新發生的一致順序達成一致。

但是,如果您希望多個變量彼此一致,那么您應該使用synchronized塊或java.util.concurrent.locks.ReentrantLock對象來保護該組變量,而忘記了volatile.

每個線程都可以將變量從主內存復制到 CPU 緩存中...

Java 中沒有“緩存”。Java 有它的內存模型。CPU 緩存是內存模型背后的隱藏原因。如果您正在為某個特定的計算機平臺實現 JVM,那么希望 Java 內存模型能夠讓您自由地利用平臺的緩存系統為您帶來好處。

如果您正在為 Java 平臺編寫代碼,那么您應該首先擔心 Java 內存模型,以及您的程序在面對它時是否會正確運行。學習高速緩存系統是一項課外活動,它可以幫助您更好地理解 Java 為何如此。


查看完整回答
反對 回復 2021-07-14
?
回首憶惘然

TA貢獻1847條經驗 獲得超11個贊

可變變量保證發生在關系之前。如果只有一個線程正在寫入而所有其他線程正在讀取一個變量,那么在這種情況下 volatile 變量可確保線程安全。在其他情況下,您必須根據需要使用其他同步機制。

僅當您的計算機包含多個 CPU 時才應使用易失性變量嗎?但是,如果我在同一個 obj 和一個 cpu 上有多個線程,它將如何表現?

操作系統調度程序為每個線程分配 CPU。每個內核可以處理一個或多個線程取決于硬件能力??勺冏兞渴钦Z言內部的抽象,它與硬件功能沒有任何直接關系。


查看完整回答
反對 回復 2021-07-14
  • 2 回答
  • 0 關注
  • 217 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號