java筆記--線程間通信

線程間通訊:

多個(gè)線程在處理同一資源,但是任務(wù)卻不同 。

比如對于同一個(gè)資源,一邊在輸入,一邊在輸出:

class Resource{
    String name;
    String sex;
}
//輸入
class Input implements Runnable{
    Resource r;
    Input(Resource r){
        this.r=r;
    }
    public void run(){
        int x=0;
        while(true){
            synchronized(r){//因?yàn)镽esource是共同操作的,所以r可以作為鎖
                if(x==0){
                    r.name="mike";
                    r.sex="nan";
                }else{
                    r.name="麗麗";
                    r.sex="女女女女";
                }
                x=(x+1)%2;
            }
        }
    }
}
//輸出
class Output implements Runnable{
    Resource r;
    Output(Resource r){
        this.r=r;
    }
    public void run(){
        while(true){
            synchronized(r){
                System.out.print(r.name+"..."+r.sex);
            }
        }
    }
}

public class TongXun {

    public static void main(String[] args) {
        //創(chuàng)建資源
        Resource r=new Resource();
        //創(chuàng)建任務(wù)
        Input in=new Input(r);
        Output out=new Output(r);
        //創(chuàng)建線程,執(zhí)行路徑
        Thread t1=new Thread(in);
        Thread t2=new Thread(out);
        //開啟線程
        t1.start();
        t2.start();
    }
}

運(yùn)行:

等待喚醒機(jī)制:

涉及的方法:

1 wait():讓線程處于凍結(jié)狀態(tài),被wait的線程會被存儲到線程池當(dāng)中。
2 notify():喚醒線程池中的任意一個(gè)線程。
3 notifyAll():喚醒線程池中的所有線程

這些方法都必須定義在同步中。
因?yàn)檫@些方法是用于操作線程狀態(tài)的方法。
必須要明確到底操作得是哪個(gè)鎖上的線程。

class Resource{
    String name;
    String sex;
    boolean flag=false;
}
//輸入
class Input implements Runnable{
    Resource r;
    Input(Resource r){
        this.r=r;
    }
    public void run(){
        int x=0;
        while(true){
            synchronized(r){//因?yàn)镽esource是共同操作的,所以r可以作為鎖
                if(r.flag)
                    try{
                        r.wait();
                        }catch(InterruptedException e){ 
                        }
                if(x==0){
                    r.name="mike";
                    r.sex="nan";
                }else{
                    r.name="麗麗";
                    r.sex="女女女女";
                }
                r.flag=true;
                r.notify();
            }
            x=(x+1)%2;
        }
    }
}
//輸出
class Output implements Runnable{
    Resource r;
    Output(Resource r){
        this.r=r;
    }
    public void run(){
        while(true){
            synchronized(r){
                if(!r.flag)
                    try{
                        r.wait();
                        }catch(InterruptedException e){ 
                        }
                System.out.println(r.name+"..."+r.sex);
                r.flag=false;
                r.notify();
            }
        }
    }
}
public class NofityDemo {

    public static void main(String[] args) {
        //創(chuàng)建資源
        Resource r=new Resource();
        //創(chuàng)建任務(wù)
        Input in=new Input(r);
        Output out=new Output(r);
        //創(chuàng)建線程,執(zhí)行路徑
        Thread t1=new Thread(in);
        Thread t2=new Thread(out);
        //開啟線程
        t1.start();
        t2.start();
    }
}

運(yùn)行:

等待喚醒機(jī)制避免了成片的輸出的現(xiàn)象,因?yàn)榈却龁拘褭C(jī)制做的就是當(dāng)一個(gè)資源被輸入,資源被占有,只有先輸出了才能再次輸入資源

思考1:wait(),notify(),notifyAll(),用來操作線程為什么定義在了Object類中?
1 這些方法存在于同步中;
2 使用這些方法時(shí)必須要標(biāo)識所屬的同步的鎖。
3 鎖可以是任意對象,所以任意對象調(diào)用的方法一定定義在Object類中。

優(yōu)化:

資源一般都是私有的,這里資源進(jìn)行私有化,并對外提供方法。

class Resource{
    private String name;
    private String sex;
    private boolean flag=false;
    
    public synchronized void set(String name,String sex){
        if(flag)
            try{
                this.wait();
                }catch(InterruptedException e){ 
                }
        this.name=name;
        this.sex=sex;
        flag=true;
        this.notify();
    }
    public synchronized void Out(){
        if(!flag)
            try{
                this.wait();
                }catch(InterruptedException e){ 
                }
        System.out.println(name+"...優(yōu)化..."+sex);
        flag=true;
        this.notify();
    }
}
//輸入
class Input implements Runnable{
    Resource r;
    Input(Resource r){
        this.r=r;
    }
    public void run(){
        int x=0;
        while(true){
            if(x==0){
                r.set("mike","nan");
            }else{
                r.set("mike","nan");
                }
            x=(x+1)%2;
            }
            
        }
    }
//輸出
class Output implements Runnable{
    Resource r;
    Output(Resource r){
        this.r=r;
    }
    public void run(){
        while(true){
            r.Out();
        }
    }
}
public class NofityDemo {

    public static void main(String[] args) {
        //創(chuàng)建資源
        Resource r=new Resource();
        //創(chuàng)建任務(wù)
        Input in=new Input(r);
        Output out=new Output(r);
        //創(chuàng)建線程,執(zhí)行路徑
        Thread t1=new Thread(in);
        Thread t2=new Thread(out);
        //開啟線程
        t1.start();
        t2.start();
    }
}

運(yùn)行:

思考2:wait(),sleep()有什么區(qū)別?
wait()釋放執(zhí)行權(quán),釋放鎖;sleep()釋放cpu執(zhí)行權(quán),不釋放鎖。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容