Java連載107-join方法、鎖(synchronized)機制以及原理

1、join方法java

1.該方法爲成員方法node

2.線程合併git

 

package com.bjpowernode.java_learning;

​

public class D107_1_JoinMethod {

  public static void main(String[] args) throws InterruptedException{

    Thread t = new Thread (new Processer107());

    t.setName("t");

    t.start();

   

    //合併線程

    t.join();//t和主線程合併,能夠理解爲兩個棧合併成一個棧了,也就是子線程與主線程合併成一個單線程了

   

    //主線程

    for(int i=0;i<5;i++) {

      System.out.println(Thread.currentThread().getName()+"-->"+i);

    }

  }

}

class Processer107 implements Runnable{

  public void run() {

    for(int i=0;i<5;i++) {

      try {

        Thread.sleep(1000);

      }catch(InterruptedException e) {

       

      }

      System.out.println(Thread.currentThread().getName()+"-->"+i);

    }

  }

}

 

 

 

2、線程的同步(加鎖)github

1.異步編程模型:線程與線程之間,獨立執行,誰也不等誰​。編程

2.同步編程模型​:線程與線程之間,先執行一個,再執行另外一個,有執行的前後順序。安全

3.​何時要同步?爲何​引入線程同步?微信

(1)​爲了數據安全,例如:銀行取款​。可是爲了​保證數據是安全的,必須加入線程同步機制;多線程

(2)​使用線程同步的情形:i.必須是​多線程環境;ii.多線程環境共享一個數據;iii.​共享的數據涉及到修改操做。異步

如下程序演示取款例子(這個不使用同步的機制,看看會產生什麼影響)異步編程

 

package com.bjpowernode.java_learning;

​

public class D107_2_SynchronizedMethod {

  public static void main(String[] args) throws InterruptedException{

    //建立一個公共帳戶

    Accout107_2 a = new Accout107_2("actno-001",8000.0);

    Processer107_2 c = new Processer107_2(a);

    //建立線程對同一個帳戶進行取款

    Thread t1 = new Thread(c);

    Thread t2 = new Thread(c);

    t1.start();

    t2.start();

   

  }

}

class Accout107_2 {

  private String actno;

  private double balance;

 

  public Accout107_2(String actno,double balance) {

    this.actno = actno;

    this.balance = balance;

  }

​

  public String getActno() {

    return actno;

  }

​

  public void setActno(String actno) {

    this.actno = actno;

  }

​

  public double getBalance() {

    return balance;

  }

​

  public void setBalance(double balance) {

    this.balance = balance;

  }

  //對外提供一個取款的方法

  public void withdraw(double money)  {

   

    double after = this.balance - money;

    try {

      //這裏咱們故意延遲了一下,能夠看出餘額不對了

      Thread.sleep(1000);

    }catch(InterruptedException e){

     

    }

    this.setBalance(after);

  }

}

class Processer107_2 implements Runnable{

  //帳戶

  Accout107_2 act;

  //Constructer

  public Processer107_2(Accout107_2 act) {

    this.act = act;

  }

  public void run() {

    act.withdraw(1000.0);

    System.out.println("取款成功,餘額爲:"+act.getBalance());

  }

}

修改一下代碼,來解決上面的問題

咱們只須要修改withdram方法便可

 

  public void withdraw(double money)  {

   

    //把須要同步的代碼,放到同步語句塊中,參數必定要填共享對象

    synchronized(this) {

      double after = this.balance - money;

      try {

        //這裏咱們故意延遲了一下,能夠看出餘額不對了

        Thread.sleep(1000);

      }catch(InterruptedException e){

       

      }

      this.setBalance(after);

    }

  }

​總結:加入線程同步機制​,能夠保證咱們的數據是安全的,而且是準確,可是這也是犧牲性能爲前提的。

3、synchronized的原理

t1線程和t2線程,t1線程執行到synchronized關鍵字,就會找this對象的對象鎖,若是找到this對象鎖,則進入到同步語句塊中執行程序,當同步語句塊中的代碼執行結束漢字事後,t1線程​歸還this的對象鎖。

在t1線程執行同步語句塊的過程當中,若是t2線程也過來執行如下代碼,也遇到了synchronized關鍵字,因此也去找this的對象鎖,可是該對象鎖被t1線程持有,只能在這等待this對象鎖​歸還。​

4、源碼:

D107_1_JoinMethod.java

D107_2_SynchronizedMethod.java

https://github.com/ruigege66/Java/blob/master/D107_1_JoinMethod.java

https://github.com/ruigege66/Java/blob/master/D107_2_SynchronizedMethod.java

2.CSDN:https://blog.csdn.net/weixin_44630050

3.博客園:https://www.cnblogs.com/ruigege0000/

4.歡迎關注微信公衆號:傅里葉變換,我的公衆號,僅用於學習交流,後臺回覆」禮包「,獲取大數據學習資料

 

相關文章
相關標籤/搜索