激情久久久_欧美视频区_成人av免费_不卡视频一二三区_欧美精品在欧美一区二区少妇_欧美一区二区三区的

服務(wù)器之家:專(zhuān)注于服務(wù)器技術(shù)及軟件下載分享
分類(lèi)導(dǎo)航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術(shù)|正則表達(dá)式|C/C++|IOS|C#|Swift|Android|VB|R語(yǔ)言|JavaScript|易語(yǔ)言|vb.net|

服務(wù)器之家 - 編程語(yǔ)言 - Java教程 - Java多線(xiàn)程volatile原理及用法解析

Java多線(xiàn)程volatile原理及用法解析

2020-07-26 00:08yaominghui Java教程

這篇文章主要介紹了Java多線(xiàn)程volatile原理及用法解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下

首先volatile有兩大功能:

保證線(xiàn)程可見(jiàn)性

禁止指令重排序

1、保證線(xiàn)程可見(jiàn)性

首先我們來(lái)看這樣一個(gè)程序,其中不加volatile關(guān)鍵字運(yùn)行的結(jié)果截然不同,加上volatile程序能夠正常結(jié)束,不加則程序進(jìn)入死循環(huán);

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
package com.designmodal.design.juc01;
 
import java.util.concurrent.TimeUnit;
 
/**
 * @author D-L
 * @Classname T001_volatile
 * @Version 1.0
 * @Description volatile 保證線(xiàn)程的可見(jiàn)性
 * @Date 2020/7/19 17:30
 */
public class T001_volatile {
  //定義一個(gè)變量running
  volatile boolean running = true;
 
  public void m(){
    while(running){
      //TODO 不做任何的處理
      System.out.println("while is running When can I stop -------------");
    }
    System.out.println("method is end ---------------");
  }
 
  public static void main(String[] args) {
    T001_volatile t001_volatile = new T001_volatile();
    new Thread(t001_volatile::m , "Thread t1").start();
 
    //停一秒
    try {
      TimeUnit.SECONDS.sleep(1);
    } catch (InterruptedException e) {
      e.printStackTrace();
    }
    //修改running的值
    t001_volatile.running = false;
  }
}

通過(guò)上面的小程序說(shuō)明volatile是具有保證線(xiàn)程之間的可見(jiàn)性的功能的,具體是如何實(shí)現(xiàn)的呢?下面給大家解釋一下:

之前在上一篇講synchronized時(shí)提到了 堆內(nèi)存是線(xiàn)程共享的,而線(xiàn)程在工作時(shí)有自己的工作內(nèi)存,對(duì)于共享變量running來(lái)說(shuō),線(xiàn)程1和線(xiàn)程2在運(yùn)行的時(shí)候先把running變量copy到自己工作內(nèi)存,對(duì)這個(gè)變量的改變都是在自己的工作內(nèi)存中,并不會(huì)直接的反映到其他線(xiàn)程,如果加了volatile,running變量改變其他線(xiàn)程很快就會(huì)知道,這就是線(xiàn)程的可見(jiàn)性;

Java多線(xiàn)程volatile原理及用法解析

這里用到的是:MESI(CPU緩存一致性協(xié)議) MESI的主要思想:當(dāng)CPU寫(xiě)數(shù)據(jù)時(shí),如果該變量是共享數(shù)據(jù),給其他CPU發(fā)送信號(hào),使得其他的CPU中的該變量的緩存行無(wú)效;歸根結(jié)底這里需要借助硬件來(lái)幫助我們。

Java多線(xiàn)程volatile原理及用法解析

volatile保證線(xiàn)程可見(jiàn)性但是不能代替synchronized:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
package com.designmodal.design.juc01;
 
import java.util.ArrayList;
import java.util.List;
 
/**
 * @author D-L
 * @Classname VolatileAndSynchronized
 * @Version 1.0
 * @Description synchronized can not be replaced by volatile
 *        volatile 不能代替synchronized
 *        只能保證可見(jiàn)性 不能保證原子性
 *        count++ 不是原子性操作
 * @Date 2020/xx/xx 23:25
 */
public class VolatileAndSynchronized {
  volatile int count = 0;
  public synchronized void m(){
    for (int i = 0; i < 1000; i++) {
      //非原子性操作 匯編指令至少有三條
      count++;
    }
  }
 
  public static void main(String[] args) {
    VolatileAndSynchronized v = new VolatileAndSynchronized();
    List<Thread> threads = new ArrayList<>();
    for (int i = 0; i < 10; i++) {
      threads.add(new Thread(v::m , "Thread"+ i));
    }
    threads.forEach(o ->o.start());
    threads.forEach(o ->{
      try {
        o.join();
      } catch (InterruptedException e) {
        e.printStackTrace();
      }
    });
    System.out.println(v.count);
  }
}

2、禁止指令重排序

指令重排序也是和CPU有關(guān)系,加了volatile之后,每次寫(xiě)都會(huì)背線(xiàn)程看到。CPU原來(lái)執(zhí)行指令時(shí),是按照一步一步順序來(lái)執(zhí)行的,但是CPU為了提高效率它會(huì)把指令并發(fā)來(lái)執(zhí)行,第一個(gè)指令執(zhí)行到一半的時(shí)候第二條指令就可能已經(jīng)開(kāi)始執(zhí)行了,這叫流水線(xiàn)式的執(zhí)行;為了充分的利用CPU,就要求編譯器把編譯完的源碼指令,可能會(huì)進(jìn)行一個(gè)指令重新排序;這種架構(gòu)通過(guò)實(shí)際驗(yàn)證,很大效率上提高了CPU的使用效率。

下面從一個(gè)面試題來(lái)討論一下指令重排序:

面試官:你聽(tīng)過(guò)單例模式嗎?

你:當(dāng)然聽(tīng)過(guò),不然沒(méi)法聊了。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
package com.designmodal.design.juc01;
 
import java.util.concurrent.TimeUnit;
 
/**
 * @author D-L
 * @Classname T002_volatile
 * @Version 1.0
 * @Description volatile 指令重排序
 * @Date 2020/7/20 00:48
 */
public class T002_volatile {
  //創(chuàng)建私有的 T002_volatile 有人會(huì)問(wèn)這里的volatile要不要使用,這里的答案是肯定的
  private static /**volatile*/ volatile T002_volatile INSTANCE;
 
  public T002_volatile() {}
 
  public T002_volatile getInstance(){
    //模擬業(yè)務(wù)代碼 這里為了synchronized更加細(xì)粒度,所以使用了雙重檢查
   if(INSTANCE == null){
     synchronized (this){
       //雙重檢查
       if(INSTANCE == null){
         //避免線(xiàn)程之間的干擾 在這里睡一秒
         try {
           TimeUnit.SECONDS.sleep(1);
         } catch (InterruptedException e) {
           e.printStackTrace();
         }
         //創(chuàng)建實(shí)例對(duì)象
         INSTANCE = new T002_volatile();
       }
     }
   }
   return INSTANCE;
  }
 
  /**
   * 創(chuàng)建100個(gè)線(xiàn)程 調(diào)用getInstance() 打印hashcode值
   * @param args
   */
  public static void main(String[] args) {
    T002_volatile t001_volatile = new T002_volatile();
    for (int i = 0; i < 100; i++) {
      new Thread(() ->{
        T002_volatile instance = t001_volatile.getInstance();
        System.out.println(instance.hashCode());
      }).start();
    }
 
  }
}

在上述的代碼中:INSTANCE = new T002_volatile(); 經(jīng)過(guò)編譯后的指令是分三步的

1、給指令申請(qǐng)內(nèi)存

2、給成員變量初始化

3、把這塊對(duì)象的內(nèi)容賦給INSTANCE

在第二步這里既然已經(jīng)有默認(rèn)值了,第二個(gè)線(xiàn)程來(lái)檢查,發(fā)現(xiàn)已經(jīng)有值了根本就不會(huì)進(jìn)入鎖住的那份代碼;加了volatile就不會(huì)出現(xiàn)指令重排序了,所以在這個(gè)時(shí)候一定要保證初始化完成之后才會(huì)賦值給這個(gè)變量,這就是volatile存在的意義。

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持服務(wù)器之家。

原文鏈接:https://www.cnblogs.com/dongl961230/p/13342688.html

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 欧美a黄 | 久久国产91 | 色七七网站| 天堂二区| 亚洲99 | 免费在线观看成人网 | 一级电影在线免费观看 | 午夜视频你懂的 | 天天草天天干天天射 | 中文字幕在线观看视频www | 国产精品一区在线免费观看 | 蜜桃欧美性大片免费视频 | 日本黄色片免费播放 | 免费午夜视频在线观看 | 日本aaa一级片 | 性大片1000免费看 | 能看的毛片网站 | av免费在线观看免费 | 日韩视频在线观看免费视频 | 日操操夜操操 | 桥本有菜免费av一区二区三区 | 国产精品一区在线看 | 国产免费片 | 摸逼逼视频 | 欧美一级黑人 | 男人的天堂视频网站 | 草人人| 亚洲成人欧美在线 | 色97在线 | 欧美综合在线观看视频 | asian gaysex| 国产一区二区三区四区波多野结衣 | 亚洲一区在线观看视频 | 性明星video另类hd | 欧美成人精品一区二区 | 日韩在线视频免费观看 | 中文字幕爱爱视频 | 亚洲乱搞 | 欧美精品v国产精品v日韩精品 | www.成人免费视频 | 亚洲一区二区免费 |