最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java線程同步、同步方法實(shí)例詳解

 更新時(shí)間:2017年04月19日 11:45:29   作者:在奮斗的大道  
本篇文章主要通過實(shí)例介紹了Java線程:線程的同步-同步方法,需要的朋友可以參考下

線程的同步是保證多線程安全訪問競(jìng)爭資源的一種手段。

線程的同步是Java多線程編程的難點(diǎn),往往開發(fā)者搞不清楚什么是競(jìng)爭資源、什么時(shí)候需要考慮同步,怎么同步等等問題,當(dāng)然,這些問題沒有很明確的答案,但有些原則問題需要考慮,是否有競(jìng)爭資源被同時(shí)改動(dòng)的問題?

對(duì)于同步,在具體的Java代碼中需要完成一下兩個(gè)操作:

把競(jìng)爭訪問的資源標(biāo)識(shí)為private;

同步哪些修改變量的代碼,使用synchronized關(guān)鍵字同步方法或代碼。

當(dāng)然這不是唯一控制并發(fā)安全的途徑。

 synchronized關(guān)鍵字使用說明

synchronized只能標(biāo)記非抽象的方法,不能標(biāo)識(shí)成員變量。 

為了演示同步方法的使用,構(gòu)建了一個(gè)信用卡賬戶,起初信用額為100w,然后模擬透支、存款等多個(gè)操作。顯然銀行賬戶User對(duì)象是個(gè)競(jìng)爭資源,而多個(gè)并發(fā)操作的是賬戶方法oper(int x),當(dāng)然應(yīng)該在此方法上加上同步,并將賬戶的余額設(shè)為私有變量,

禁止直接訪問。

/** 
* Java線程:線程的同步 
* 
* @author leizhimin 2009-11-4 11:23:32 
*/ 
public class Test { 
  public static void main(String[] args) { 
    User u = new User("張三", 100); 
    MyThread t1 = new MyThread("線程A", u, 20); 
    MyThread t2 = new MyThread("線程B", u, -60); 
    MyThread t3 = new MyThread("線程C", u, -80); 
    MyThread t4 = new MyThread("線程D", u, -30); 
    MyThread t5 = new MyThread("線程E", u, 32); 
    MyThread t6 = new MyThread("線程F", u, 21); 
    t1.start(); 
    t2.start(); 
    t3.start(); 
    t4.start(); 
    t5.start(); 
    t6.start(); 
  } 
} 
class MyThread extends Thread { 
  private User u; 
  private int y = 0; 
   MyThread(String name, User u, int y) { 
    super(name); 
    this.u = u; 
    this.y = y; 
  } 
  public void run() { 
    u.oper(y); 
  } 
} 
class User { 
  private String code; 
  private int cash; 
  User(String code, int cash) { 
    this.code = code; 
    this.cash = cash; 
  } 
  public String getCode() { 
    return code; 
  } 
  public void setCode(String code) { 
    this.code = code; 
  } 
  /** 
   * 業(yè)務(wù)方法 
   * @param x 添加x萬元 
   */ 
  public synchronized void oper(int x) { 
    try { 
      Thread.sleep(10L); 
      this.cash += x; 
      System.out.println(Thread.currentThread().getName() + "運(yùn)行結(jié)束,增加“" + x + "”,當(dāng)前用戶賬戶余額為:" + cash); 
      Thread.sleep(10L); 
    } catch (InterruptedException e) { 
      e.printStackTrace(); 
    } 
  } 
  @Override 
  public String toString() { 
    return "User{" + 
        "code='" + code + '\'' + 
        ", cash=" + cash + 
        '}'; 
  } 
} 

輸出結(jié)果:

線程A運(yùn)行結(jié)束,增加“20”,當(dāng)前用戶賬戶余額為:120 
線程F運(yùn)行結(jié)束,增加“21”,當(dāng)前用戶賬戶余額為:141 
線程E運(yùn)行結(jié)束,增加“32”,當(dāng)前用戶賬戶余額為:173 
線程C運(yùn)行結(jié)束,增加“-80”,當(dāng)前用戶賬戶余額為:93 
線程B運(yùn)行結(jié)束,增加“-60”,當(dāng)前用戶賬戶余額為:33 
線程D運(yùn)行結(jié)束,增加“-30”,當(dāng)前用戶賬戶余額為:3 

反面教材,不同步的情況,也就是去掉oper(int x)方法的synchronized修飾符,然后運(yùn)行程序,結(jié)果如下:

線程A運(yùn)行結(jié)束,增加“20”,當(dāng)前用戶賬戶余額為:61 
線程D運(yùn)行結(jié)束,增加“-30”,當(dāng)前用戶賬戶余額為:63 
線程B運(yùn)行結(jié)束,增加“-60”,當(dāng)前用戶賬戶余額為:3 
線程F運(yùn)行結(jié)束,增加“21”,當(dāng)前用戶賬戶余額為:61 
線程E運(yùn)行結(jié)束,增加“32”,當(dāng)前用戶賬戶余額為:93 
線程C運(yùn)行結(jié)束,增加“-80”,當(dāng)前用戶賬戶余額為:61 

很顯然,上面的結(jié)果是錯(cuò)誤的,導(dǎo)致錯(cuò)誤的原因是多個(gè)線程并發(fā)訪問了競(jìng)爭資源u,并對(duì)u的屬性做了改動(dòng)。

可見同步的重要性。 

注意:

通過前文可知,線程退出同步方法時(shí)將釋放掉方法所屬對(duì)象的鎖,但還應(yīng)該注意的是,同步方法中還可以使用特定的方法對(duì)線程進(jìn)行調(diào)度。這些方法來自于java.lang.Object類。

void notify()  
     喚醒在此對(duì)象監(jiān)視器上等待的單個(gè)線程。  
void notifyAll()  
     喚醒在此對(duì)象監(jiān)視器上等待的所有線程。  
void wait()  
     導(dǎo)致當(dāng)前的線程等待,直到其他線程調(diào)用此對(duì)象的 notify() 方法或 notifyAll() 方法。  
void wait(long timeout)  
     導(dǎo)致當(dāng)前的線程等待,直到其他線程調(diào)用此對(duì)象的 notify() 方法或 notifyAll() 方法,或者超過指定的時(shí)間量。  
void wait(long timeout, int nanos)  
     導(dǎo)致當(dāng)前的線程等待,直到其他線程調(diào)用此對(duì)象的 notify() 方法或 notifyAll() 方法,或者其他某個(gè)線程中斷當(dāng)前線程,或者已超過某個(gè)實(shí)際時(shí)間量 

結(jié)合以上方法,處理多線程同步與互斥問題非常重要,著名的生產(chǎn)者-消費(fèi)者例子就是一個(gè)經(jīng)典的例子,任何語言多線程必學(xué)的例子。 

希望本篇文章對(duì)小伙伴們有所幫助

相關(guān)文章

  • 一文帶你了解SpringBoot的啟動(dòng)原理

    一文帶你了解SpringBoot的啟動(dòng)原理

    大家通常只需要給一個(gè)類添加一個(gè)@SpringBootApplication 注解,然后再加一個(gè)main 方法里面固定的寫法 SpringApplication.run(Application.class, args);那么spring boot 到底是如何啟動(dòng)服務(wù)的呢,接下來咱們通過源碼解析,需要的朋友可以參考下
    2023-05-05
  • 淺談一段java代碼是如何執(zhí)行的

    淺談一段java代碼是如何執(zhí)行的

    這篇文章主要介紹了淺談一段java代碼是如何執(zhí)行的,小編覺得不錯(cuò),下面就一起來了解一下
    2021-04-04
  • java HashMap詳解及實(shí)例代碼

    java HashMap詳解及實(shí)例代碼

    這篇文章主要介紹了java HashMap詳解及實(shí)例代碼的相關(guān)資料,需要的朋友可以參考下
    2017-01-01
  • 詳解SpringMVC的url-pattern配置及原理剖析

    詳解SpringMVC的url-pattern配置及原理剖析

    這篇文章主要介紹了SpringMVC的url-pattern配置及原理剖析,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-06-06
  • Java實(shí)現(xiàn)lucene搜索功能的方法(推薦)

    Java實(shí)現(xiàn)lucene搜索功能的方法(推薦)

    下面小編就為大家?guī)硪黄狫ava實(shí)現(xiàn)lucene搜索功能的方法(推薦)。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2016-12-12
  • Spring Boot2.0使用Spring Security的示例代碼

    Spring Boot2.0使用Spring Security的示例代碼

    這篇文章主要介紹了Spring Boot2.0使用Spring Security的示例代碼,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2018-08-08
  • 分析xxljob登入功能集成OIDC的統(tǒng)一認(rèn)證

    分析xxljob登入功能集成OIDC的統(tǒng)一認(rèn)證

    這篇文章主要為大家介紹分析xxljob登入功能集成OIDC的統(tǒng)一認(rèn)證的詳解說明,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步
    2022-02-02
  • Java中的反射機(jī)制示例詳解

    Java中的反射機(jī)制示例詳解

    反射就是把Java類中的各個(gè)成分映射成一個(gè)個(gè)的Java對(duì)象。本文將通過示例詳細(xì)講解Java中的反射機(jī)制,感興趣的小伙伴可以跟隨小編學(xué)習(xí)一下
    2022-03-03
  • IDEA搭建Maven模塊化項(xiàng)目的實(shí)現(xiàn)

    IDEA搭建Maven模塊化項(xiàng)目的實(shí)現(xiàn)

    本文主要介紹了IDEA搭建Maven模塊化項(xiàng)目的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-05-05
  • java使用Hashtable過濾數(shù)組中重復(fù)值的方法

    java使用Hashtable過濾數(shù)組中重復(fù)值的方法

    這篇文章主要介紹了java使用Hashtable過濾數(shù)組中重復(fù)值的方法,涉及java數(shù)組遍歷及過濾的相關(guān)技巧,需要的朋友可以參考下
    2016-08-08

最新評(píng)論

梧州市| 监利县| 阳东县| 霞浦县| 太仆寺旗| 白水县| 肇庆市| 上栗县| 陕西省| 北辰区| 新民市| 荣昌县| 原平市| 阿城市| 元谋县| 勐海县| 华蓥市| 金沙县| 洪洞县| 蒙阴县| 万源市| 防城港市| 都江堰市| 游戏| 上犹县| 莆田市| 昆山市| 郴州市| 德清县| 承德市| 青冈县| 崇礼县| 蓝田县| 磐安县| 阳原县| 色达县| 潞西市| 伊川县| 荣成市| 柏乡县| 项城市|