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