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

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

PHP教程|ASP.NET教程|JAVA教程|ASP教程|編程技術|正則表達式|

服務器之家 - 編程語言 - JAVA教程 - 詳談Java多線程的幾個常用關鍵字

詳談Java多線程的幾個常用關鍵字

2020-09-20 12:38Java之家 JAVA教程

下面小編就為大家帶來一篇詳談Java多線程的幾個常用關鍵字。小編覺得挺不錯的,現在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧

一、同步(synchronized)和異步(asynchronized)

1、同步(synchronized)簡單說可以理解為共享的意思,如果資源不是共享的,就沒必要進行同步。設置共享資源為同步的話,可以避免一些臟讀情況。

2、異步(asynchronized)簡單說可以理解為獨立不受到其他任何制約。

舉個例子:

線程1調用了帶有synchronized關鍵字的方法methodA,線程2調用了異步方法methodB,出現的現象是同時控制臺輸出 t1,t2。

?
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
package com.ietree.multithread.sync;
 
/**
 * 多線程之對象同步鎖和異步鎖Demo
 *
 * @author ietree
 */
public class SynAndAsynDemo {
 
  public static void main(String[] args) {
    
    final SynAndAsynDemo mo = new SynAndAsynDemo();
    
    Thread t1 = new Thread(new Runnable() {
      @Override
      public void run() {
        mo.methodA();
      }
    },"t1");
    
    Thread t2 = new Thread(new Runnable() {
      @Override
      public void run() {
        mo.methodB();
      }
    },"t2");
    
    t1.start();
    t2.start();
  }
  
  // 方法A
  public synchronized void methodA(){
    try {
      System.out.println(Thread.currentThread().getName());
      // 休眠4秒
      Thread.sleep(4000);
    } catch (InterruptedException e) {
      e.printStackTrace();
    }
  }
  
  // 方法B
  public void methodB(){
    System.out.println(Thread.currentThread().getName());
  }
  
}

線程1調用了帶有synchronized關鍵字的方法methodA,線程2調用了帶有synchronized關鍵字的方法methodB,出現的現象是首先輸出t1,等待4秒之后再輸出t2。

?
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
package com.ietree.multithread.sync;
 
/**
 * 多線程之對象同步鎖和異步鎖Demo
 *
 * @author ietree
 */
public class SynAndAsynDemo {
 
  public static void main(String[] args) {
    
    final SynAndAsynDemo mo = new SynAndAsynDemo();
    
    Thread t1 = new Thread(new Runnable() {
      @Override
      public void run() {
        mo.methodA();
      }
    },"t1");
    
    Thread t2 = new Thread(new Runnable() {
      @Override
      public void run() {
        mo.methodB();
      }
    },"t2");
    
    t1.start();
    t2.start();
  }
  
  // 方法A
  public synchronized void methodA(){
    try {
      System.out.println(Thread.currentThread().getName());
      // 休眠4秒
      Thread.sleep(4000);
    } catch (InterruptedException e) {
      e.printStackTrace();
    }
  }
  
  // 方法B
  public synchronized void methodB(){
    System.out.println(Thread.currentThread().getName());
  }
  
}

結論:

在第一段代碼中t1線程先持有object對象的Lock鎖,t2線程可以以異步的方式調用對象中的非synchronized修飾的方法,所以同時輸出;

在第二段代碼中t1線程先持有object對象的Lock鎖,t2線程如果在這個時候調用對象中的同步(synchronized)方法則需等待,也就是同步。

二、volatile

作用:volatile關鍵字的作用是:使變量在多個線程間可見(具有可見性),但是僅靠volatile是不能保證線程的安全性,volatile關鍵字不具備synchronized關鍵字的原子性。

Demo1:

?
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
package com.ietree.multithread.sync;
 
public class RunThread extends Thread {
  // volatile
  private boolean isRunning = true;
 
  private void setRunning(boolean isRunning) {
    this.isRunning = isRunning;
  }
 
  public void run() {
    System.out.println("進入run方法..");
    int i = 0;
    while (isRunning == true) {
      // ..
    }
    System.out.println("線程停止");
  }
 
  public static void main(String[] args) throws InterruptedException {
    RunThread rt = new RunThread();
    rt.start();
    Thread.sleep(1000);
    rt.setRunning(false);
    System.out.println("isRunning的值已經被設置了false");
  }
}

程序輸出:

?
1
2
3
4
進入run方法..
isRunning的值已經被設置了false
 
之后進入死循環

Demo2:

?
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
package com.ietree.multithread.sync;
 
public class RunThread extends Thread {
  // volatile
  private volatile boolean isRunning = true;
 
  private void setRunning(boolean isRunning) {
    this.isRunning = isRunning;
  }
 
  public void run() {
    System.out.println("進入run方法..");
    int i = 0;
    while (isRunning == true) {
      // ..
    }
    System.out.println("線程停止");
  }
 
  public static void main(String[] args) throws InterruptedException {
    RunThread rt = new RunThread();
    rt.start();
    Thread.sleep(1000);
    rt.setRunning(false);
    System.out.println("isRunning的值已經被設置了false");
  }
}

程序輸出:

?
1
2
isRunning的值已經被設置了false
線程停止

總結:當多個線程之間需要根據某個條件確定 哪個線程可以執行時,要確保這個條件在 線程之間是可見的。因此,可以用volatile修飾。

volatile 與 synchronized 的比較:

①volatile輕量級,只能修飾變量。synchronized重量級,還可修飾方法

②volatile只能保證數據的可見性,不能用來同步,因為多個線程并發訪問volatile修飾的變量不會阻塞。

synchronized不僅保證可見性,而且還保證原子性,因為,只有獲得了鎖的線程才能進入臨界區,從而保證臨界區中的所有語句都全部執行。多個線程爭搶synchronized鎖對象時,會出現阻塞。

線程安全性包括兩個方面,①可見性。②原子性。

從上面自增的例子中可以看出:僅僅使用volatile并不能保證線程安全性。而synchronized則可實現線程的安全性。

以上這篇詳談Java多線程的幾個常用關鍵字就是小編分享給大家的全部內容了,希望能給大家一個參考,也希望大家多多支持服務器之家。

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 网红刘婷hd国产高清 | 国产一区二区三区高清 | 天堂一区二区在线观看 | 久久中文电影 | 2020中文字幕| a级亚洲片精品久久久久久久 | 无码区国产区在线播放 | 午夜国产精品福利在线观看 | 大又大又黄又爽免费毛片 | 成人国产精品视频频 | yellow在线 | 亚洲gogo人体大胆西西安徽 | 精品国产乱码久久久人妻 | 国产1区2区三区不卡 | 日韩精品欧美高清区 | 狠狠色综合久久久久尤物 | 边打电话边操 | 国产精品一区三区 | 欧美x×x | 亚洲国产精品二区久久 | 美女禁区视频无遮挡免费看 | 午夜AV亚洲一码二中文字幕青青 | 俄罗斯妈妈k8影院在线观看 | 精品国产品香蕉在线观看75 | 国产精品二区高清在线 | 国产福利在线观看91精品 | 亚洲 欧美 中文 日韩 视频 | 五月天91 | 国产1区2区三区不卡 | chinese老太grandma | 成年人视频免费在线观看 | 亚洲精品卡1卡二卡3卡四卡 | 亚洲午夜性春猛交xxxx | 国产伦精品一区二区三区免费迷 | 欧美日韩国内 | 999热在线精品观看全部 | 国产免费午夜高清 | 欧美做受 | 动漫美女被吸乳羞羞小说 | 好男人好资源在线观看 | 日韩精品一区二区三区中文在线 |