欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

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

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

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

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

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

把競爭訪問的資源標(biāo)識為private;

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

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

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

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

為了演示同步方法的使用,構(gòu)建了一個信用卡賬戶,起初信用額為100w,然后模擬透支、存款等多個操作。顯然銀行賬戶User對象是個競爭資源,而多個并發(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é)果是錯誤的,導(dǎo)致錯誤的原因是多個線程并發(fā)訪問了競爭資源u,并對u的屬性做了改動。

可見同步的重要性。 

注意:

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

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

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

希望本篇文章對小伙伴們有所幫助

相關(guān)文章

  • 理解Java訪問權(quán)限控制

    理解Java訪問權(quán)限控制

    這篇文章主要幫助大家深入的理解Java訪問權(quán)限控制,為何需要訪問控制權(quán)限,本文給出了解釋,感興趣的小伙伴們可以參考一下
    2016-02-02
  • 教你如何使用Java多線程編程LockSupport工具類

    教你如何使用Java多線程編程LockSupport工具類

    在Java工具包中有一個LockSupport工具類,主要負(fù)責(zé)掛起和喚醒線程,這篇文章主要介紹了教你如何使用Java多線程編程LockSupport工具類,需要的朋友可以參考下
    2021-04-04
  • SpringBoot整合JDBC、Druid數(shù)據(jù)源的示例代碼

    SpringBoot整合JDBC、Druid數(shù)據(jù)源的示例代碼

    這篇文章主要介紹了SpringBoot整合JDBC、Druid數(shù)據(jù)源,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-05-05
  • mybaits-spring的實(shí)現(xiàn)方式

    mybaits-spring的實(shí)現(xiàn)方式

    這篇文章主要介紹了mybaits-spring的實(shí)現(xiàn)方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-05-05
  • Java中hashMap遍歷的9種方式

    Java中hashMap遍歷的9種方式

    hashMap是非常重要的容器類,本文主要介紹了Java中hashMap遍歷的9種方式,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2024-06-06
  • Java并發(fā)問題之樂觀鎖與悲觀鎖

    Java并發(fā)問題之樂觀鎖與悲觀鎖

    這篇文章主要介紹了Java并發(fā)問題之樂觀鎖與悲觀鎖,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-12-12
  • Java實(shí)現(xiàn)將類數(shù)據(jù)逐行寫入CSV文件的方法詳解

    Java實(shí)現(xiàn)將類數(shù)據(jù)逐行寫入CSV文件的方法詳解

    這篇文章主要為大家詳細(xì)介紹了Java如何實(shí)現(xiàn)將類數(shù)據(jù)逐行寫入CSV文件,文中的示例代碼講解詳細(xì),具有一定的參考價值,需要的可以借鑒一下
    2022-11-11
  • JAVA  字符串加密、密碼加密實(shí)現(xiàn)方法

    JAVA 字符串加密、密碼加密實(shí)現(xiàn)方法

    這篇文章主要介紹了JAVA 字符串加密、密碼加密實(shí)現(xiàn)方法的相關(guān)資料,需要的朋友可以參考下
    2016-10-10
  • 詳解Java讀取Jar中資源文件及示例代碼

    詳解Java讀取Jar中資源文件及示例代碼

    這篇文章主要介紹了詳解Java讀取Jar中資源文件及實(shí)現(xiàn)代碼的相關(guān)資料,在開發(fā)java項目的時候,經(jīng)常會用到j(luò)ar包,這里就說下如何讀取,需要的朋友可以參考下
    2017-07-07
  • RabbitMQ延遲隊列及消息延遲推送實(shí)現(xiàn)詳解

    RabbitMQ延遲隊列及消息延遲推送實(shí)現(xiàn)詳解

    這篇文章主要介紹了RabbitMQ延遲隊列及消息延遲推送實(shí)現(xiàn)詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2019-12-12

最新評論