目錄
一、主線程與子線程基礎通信
1.1 主線程向子線程傳遞數據
二、子線程向主線程返回數據
2.1 通過共享變量方式
2.2 同步塊中使用wait/notify機制
2.3?Lock和Condition實現線程通信機制
一、主線程與子線程基礎通信
1.1 主線程向子線程傳遞數據
-
通過構造函數傳遞參數:主線程通過UserThread的構造函數將數據a傳遞給子線程
package com.demo6;public class Test {public static void main(String[] args) {System.out.println(Thread.currentThread().getName()+",主線程");int a = 10;UserThread u = new UserThread(a);u.start();}
}
package com.demo6;public class UserThread extends Thread{int a ;public UserThread(int a){this.a = a;}public void run(){System.out.println(Thread.currentThread().getName()+",執行run方法"+",a的值為:"+a);}}
-
輸出結果:主線程創建子線程后,子線程輸出接收到的參數值
二、子線程向主線程返回數據
2.1 通過共享變量方式
-
sleep等待:主線程通過sleep等待子線程完成計算
-
共享變量:子線程將計算結果存儲在成員變量中,主線程通過getter方法獲取
-
缺點:sleep時間難以精確控制,可能等待過長或過短
package com.demo7;public class Test {public static void main(String[] args) {UserThread ut =new UserThread();ut.start();try {Thread.sleep(5*1000);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}System.out.println("主線程通過getter方法獲取的值為: "+ut.getSum());}}
package com.demo7;public class UserThread extends Thread{private int sum = 0;public void run(){for(int i=0;i<=100;i++){this.sum +=i;}}public int getSum(){return this.sum;}}
運行結果:
2.2 同步塊中使用wait/notify機制
-
同步協作:主線程和子線程使用同一個對象鎖進行同步
-
wait/notify機制:主線程等待,子線程完成后通知主線程
(1)當主線程持有的是當前線程類對象的鎖,如果是當前線程類對象的自己this和父類(Object/Thread.class/接口父類.class),都可以通知解鎖。?都可以顯示的或隱式的寫notify。
package com.demo13;public class Test {public static void main(String[] args) {UserThread u = new UserThread();u.start();//線程通信的必須的條件是:同一個對象//如果持有的是當前線程類對象的鎖,如果是當前線程類對象的自己this和父類,都可以通知解鎖//都可以顯示的或隱式的寫notifysynchronized (u) {try {//主線程持有u對象的鎖,被阻塞u.wait();} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}System.out.println("主線程獲取的值為:"+u.getSum());}}}
package com.demo13;public class UserThread extends Thread implements IUser{private int sum = 0;Object obj = new Object();public void run(){// synchronized (this) {
// for(int i=0;i<=100; i++)
// {
// sum+=i;
// }
// this.notify();
// }// synchronized (Thread.class) {
// for(int i=0;i<=100; i++)
// {
// sum+=i;
// }
// }// synchronized (obj) {
// for(int i=0;i<=100; i++)
// {
// sum+=i;
// }
// }synchronized (IUser.class) {for(int i=0;i<=100; i++){sum+=i;}}}public int getSum(){return this.sum;}}
package com.demo13;public interface IUser {}
運行結果:
(2)當主線程持有的是非線程類對象的鎖,子線程持有的也只能是非線程類對象的鎖。這是只能顯示的寫notify。
package com.demo13;public class Test {public static void main(String[] args) {User u1 = new User();UserThread u = new UserThread(u1);u.start();synchronized (u1) {try {//主線程持有u1對象的鎖,內阻塞u1.wait();} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}System.out.println("主線程獲取的值為:"+u.getSum());}}}
package com.demo13;public class UserThread extends Thread implements IUser{private int sum = 0;User u1;public UserThread(User u1) {this.u1 = u1;}public void run(){synchronized (u1) {for(int i=0;i<=100; i++){sum+=i;}//顯示解鎖u1.notify();}}public int getSum(){return this.sum;}}
package com.demo13;public class User {}
運行結果:
如果子線程又new了User類對象u1,此時主線程和子線程的u1不是同一個對象,會發生死鎖:
2.3?Lock和Condition實現線程通信機制
????????這是一種基于明鎖(Lock)和條件變量(Condition)的線程通信機制,屬于JUC包中的高級同步機制。
? ? ?工作流程:
-
創建鎖和條件:主線程創建ReentrantLock和Condition對象
-
傳遞資源:將鎖和條件傳遞給子線程
-
主線程等待:主線程獲取鎖后調用cond.await()進入等待狀態
-
子線程執行:子線程獲取鎖,執行計算任務
-
發送信號:子線程完成任務后調用cond.signal()喚醒主線程
-
結果獲取:主線程被喚醒后獲取并輸出計算結果
package com.demo31;import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;public class Test {public static void main(String[] args) {Lock lock = new ReentrantLock();// 通過鎖創建條件變量Condition cond =lock.newCondition();UserThread u1 = new UserThread(lock,cond);u1.start();lock.lock();try {// 主線程等待條件信號cond.await();// 收到信號后輸出計算結果System.out.println(u1.getSum());} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}// 手動釋放鎖lock.unlock();}}
package com.demo31;import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;public class UserThread extends Thread {private Lock lock;private int sum;private Condition cond;public UserThread(Lock lock,Condition cond) {this.lock = lock;this.cond =cond;}public void run() {lock.lock();for (int i = 0; i <= 100; i++) {try {Thread.sleep(200);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}this.sum += i;}// 發送條件信號,喚醒等待的線程this.cond.signal();// 釋放鎖this.lock.unlock();}public int getSum(){return this.sum;}}
運行結果: