一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - Java教程 - Java Synchronize下的volatile關鍵字詳解

Java Synchronize下的volatile關鍵字詳解

2021-08-23 14:43Ryan kk Java教程

這篇文章主要介紹了Java Synchronize下的volatile關鍵字詳解,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下

簡介關鍵詞:Synchronize與volatile

  • Synchronize:無論是對于Synchronize同步方法異或是Synchronize塊,本質是對某對象或某類加鎖,讓多線程進行隊列化的有序地同步執行。
  • volatile:用于修飾變量。在多線程執行過程中,禁止線程從工作內存(緩存)中讀取值。

volatile問題拋出:

讓我們看到這樣一個問題,我們設置一個含有boolean標志位的類Test,以及兩個Runable接口實例,分別為MyThread1,MyThread2。
在MyThread1中通過while循環判斷flag是否更改,如果更改便結束循環退出。
在MyThread2中改變flag值。
代碼如下:
Test:

  1. public class Test {
  2. boolean flag = true;
  3. }

MyThread1:

  1. public class MyThread1 implements Runnable{
  2.  
  3. Test test;
  4.  
  5. public MyThread1(Test test){
  6. this.test = test;
  7. }
  8.  
  9. @Override
  10. public void run() {
  11.  
  12. while (test.flag){
  13.  
  14. }
  15.  
  16. System.out.println(Thread.currentThread().getName()+" 我已退出");
  17. }
  18.  
  19. }

MyThread2:

  1. public class MyThread2 implements Runnable{
  2.  
  3. Test test;
  4.  
  5. public MyThread2(Test test){
  6. this.test = test;
  7. }
  8.  
  9. @Override
  10. public void run() {
  11.  
  12. try {
  13. Thread.sleep(3000);
  14. } catch (InterruptedException e) {
  15. e.printStackTrace();
  16. }
  17.  
  18. test.flag = false;
  19.  
  20. }
  21. }

main函數:

  1. public static void main(String[] args) {
  2.  
  3. Test test = new Test();
  4.  
  5. MyThread1 myThread1 = new MyThread1(test);
  6. MyThread2 myThread2 = new MyThread2(test);
  7.  
  8. Thread thread1 = new Thread(myThread1);
  9. Thread thread2 = new Thread(myThread2);
  10.  
  11. thread1.start();
  12. try {
  13. Thread.sleep(1000);
  14. } catch (InterruptedException e) {
  15. e.printStackTrace();
  16. }
  17. thread2.start();
  18.  
  19. }
  • 按照我們常規的想法,在在Sleep延時之后,Thread2會更改flag的值。而Thread1也會因此退出循環。
  • 但實際上,Thread1并沒有因此退出循環。
  • 原因是Thread1并未從內存中讀取flag,而是直接從工作內存中讀取。所以即便是Thread2已經更新了flag的值,但Thread1工作內存中的flag也并未更新。所以便導致了Thread1陷入死循環。

Java Synchronize下的volatile關鍵字詳解

解決方法:

那么如何解決這樣的問題呢?
很簡單,使用volatile關鍵字。讓線程不得不從主內存中讀取flag值。

  1. volatile boolean flag = true;

在我們添加volatile關鍵字后,Thread1便可以正常退出。

在Synchronize下的volatile:

此時我們已經了解了volatile關鍵字的作用,那么在我們的volatile關鍵字中,Synchronize有著怎樣的作用呢?

volatile問題拋出:

其實在我們實際使用中,volatile其實也是有一些隱患的。
例如:我們創造10條線程,每條線程都使volatile修飾的int常量增加1000000次。

  1. public class MyThread1 implements Runnable{
  2.  
  3. volatile int num = 0;
  4.  
  5. @Override
  6. public void run() {
  7.  
  8. for (int i = 0; i < 1000000; i++) {
  9. num++;
  10. System.out.println(Thread.currentThread().getName()+" "+num);
  11. }
  12.  
  13. }
  14.  
  15. public static void main(String[] args) {
  16.  
  17. MyThread1 myThread1 = new MyThread1();
  18.  
  19. Thread[] arr = new Thread[10];
  20.  
  21. for (int i = 0; i < 10; i++) {
  22. arr[i] = new Thread(myThread1);
  23. }
  24.  
  25. for (int i = 0; i < 10; i++) {
  26. arr[i].start();
  27. }
  28.  
  29. }
  30.  
  31. }

Java Synchronize下的volatile關鍵字詳解

分析:

  • 從結果中,我們可以看到,num并沒有像我們想象一樣達到10000000。
  • 這是因為volatile所修飾的int變量在自加過程中并非原子操作。這也就是說這個自加的過程可以被打斷??梢员环纸鉃椋韩@取值,自加,賦值三個步驟。
  • 例如當,num = 0時,Thread1獲取了num的值,并賦值為1,但此時在Thread1還未來得及更新線程的時候,Thread的2以及Thread3已經將線程的值更新為2,但Thread1再賦值,num的值又會重新變為1。
  • 所以,我們便需要在自加的過程中添加Synchronize關鍵字,讓線程實現同步。

結論:

在我們使用volatile關鍵字時,需要注意操作是否為原子操作,以免造成線程不安全。

擴展:

其實,對于原子操作,Java已經提供了Atomic原子類來解決。其中涉及了CAS機制,在不使用Synchronize的情況下,通過比較原值與當前值,不但性能高效,并且也能達到線程安全的目的。

到此這篇關于Synchronize下的volatile關鍵字 的文章就介紹到這了,更多相關Synchronize volatile關鍵字 內容請搜索服務器之家以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持服務器之家!

原文鏈接:https://blog.csdn.net/weixin_49422995/article/details/114642289

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 国产亚洲精aa在线观看不卡 | 91免费高清视频 | ak福利午夜在线观看 | 希岛爱理aⅴ在线中文字幕 午夜综合网 | 毛片应用 | 500福利第一巨人导航 | 亚洲AV蜜桃永久无码精品无码网 | 国产a一级毛片午夜剧院 | 草逼视频网址 | 四虎永久在线精品免费影视 | 四虎精品免费视频 | 东京干福利| 亚洲成人影院在线观看 | 国产成人激情视频 | 日本伊人久久 | 91精品婷婷国产综合久久8 | 91精品国产在线 | 免费草比视频 | 亚洲卡一卡2卡三卡4麻豆 | 亚洲欧美日韩中文字幕网址 | ysl千人千色t9t9t9t9| 天堂a视频 | 大好硬好深好爽想要视频 | 精品一区二区三区高清免费不卡 | 国产视频一区在线观看 | 国产国语videosex另类 | 成人依依网 | 亚洲色图.com| 范冰冰好紧好滑好湿 | 日本午夜小视频 | 91久久青青青国产免费 | 国语对白做受xxxx | 日韩一区二区三区不卡视频 | 四大美女思春艳史片 | porno美国xxxx| 17岁俄罗斯csgo | 蛮荒的童话未删减在线观看 | 果冻传媒在线播放观看w | 草莓永久地域网名入2022 | 国产91素人搭讪系列天堂 | 久久亚洲一级α片 |