/** * 多線程之間的通信 * * 1.什麼是線程通信呢? * 就是多個線程操做同一個資源,但任務不一樣 * * * 2.打個不恰當的比喻 : * 以藥品的買賣爲列子 * 一我的負責賣藥品 * 一我的負責進口藥品 * * 請問? * 這個是否是說,2我的在操做同一個資源「藥品呢」?是的 * 可是他們兩我的負責的任務倒是不同的 * * 一個任務是賣藥品 * 一個任務是進口藥品 * * 這個就叫線程之間的通信 * * 3.線程安全的問題? * 涉及到多線程,無論你是作什麼的,一概都會存在線程安全的問題 * 這裏牽扯一個CPU的問題 * * 3.1 CPU的執行資格 * 什麼是CPU執行資格 * 說白了吧 過於底層不說,沒意思 * 打個比喻 * 我如今建立 A B C D 4個任務,開啓線程了 * 那麼如今這個4個任務就具有了CPU執行資格並加入了執行隊列中 * * 簡單來講執行資格爲,我具有了被CPU處理的執行 * 3.2CPU的執行權 * 說白了, ABCD個任務, 好比 當前CPU對 A正在處理 * 那麼A就有CPU的執行權 * * 簡單點說執行權,我正在被CPU處理 * * 這個多線程啊,事實上並非,多個線程同時運行, * 其實就CPU在多個任務(也就線程嘛)之間快速的來回切換 * * (來回切換啊)那就會涉及一個問題 * CPU正在處理A任務,還沒處理完,CP U忽然就切換到B處去處理B了 * 這就是所謂的線程安全問題? * * 解決方式爲,同步鎖 java 有個前提是,多個線程必須共享的同一個資源 * -- 同步函數 --同步代碼塊 * 其實PHP雖然不支持多線程 * 可是也會碰到相似的問題 * 那就在高併發的時候處理一個 任務,也會出現的問題, * 解決方式其實原理與java中同步鎖是一個原理,咱們叫文件鎖 * * 說白了吧,就是同一時刻只能有一個線程在操做我,其餘的不行 * * **/ //藥品資源 class DrugResource { String DrugName; /*藥品名字*/ String Drugtype; /*西藥or中藥*/ } /**進口藥品****/ class ImportDrugs implements Runnable { DrugResource d;//藥品資源對象,保證,兩個任務操做同一個對象 ImportDrugs(DrugResource d){ this.d = d; } public void run() { imports(); } public void imports() { int x = 0 ; while(true) { synchronized(d){ //同步鎖也是同步代碼塊 前提是公用一個對象 d就是一個公用對象 if(x==0) //來回切換這個if--sele 取模運算給我線程沒啥關係只是讓他來顯示看見的效果比較好 { d.DrugName = "penicillin -青黴素"; d.Drugtype = "penicillin -西藥="; } else { // d.DrugName = "雲南白藥"; //d.Drugtype = "中藥"; } x = (x+1)%2; //解釋 x = (x+1)%2; /** * x =0時候 * (0+1)%2 * 1%2 = 1 * * x=1; * (1+1)%2 = 2%2 = 0 * * 這樣就能切換了 * 這個東西沒意義,可是仍是解釋一下 */ } } } } /**賣藥品****/ class SellDrugs implements Runnable { DrugResource d ; //藥品資源對象,保證,兩個任務操做同一個對象 SellDrugs(DrugResource d){ this.d = d; } public void run() { /**線程入口程序*/ sell(); } public void sell(){ while(true) { synchronized(d){ //Thread.currentThread().getName() 取出當前運行中進程名 System.out.println(Thread.currentThread().getName()+"賣出了.."+d.DrugName+"--品種--"+d.Drugtype); } } } } class TreadResource { public static void main(String[] args) { DrugResource d = new DrugResource(); //資源對象 ImportDrugs work1 = new ImportDrugs(d) ; //任務對象一 進口任務 SellDrugs work2 = new SellDrugs(d) ; //任務對象二 賣任務 /*********執行路徑********/ Thread t1 = new Thread(work1); Thread t2 = new Thread(work2); t1.start(); //開啓線程 t2.start(); //開啓線程 } }