溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

線程間通訊

發(fā)布時(shí)間:2020-07-07 11:25:29 來(lái)源:網(wǎng)絡(luò) 閱讀:343 作者:灰白世界 欄目:編程語(yǔ)言

什么是多線程通訊?

多線程通訊就是多個(gè)線程同時(shí)操作一個(gè)資源,但是操作的動(dòng)作不同

代碼實(shí)現(xiàn)

package com.kernel;

class Res {
    private String name;
    private String sex;
    private Boolean flag;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public Boolean getFlag() {
        return flag;
    }

    public void setFlag(Boolean flag) {
        this.flag = flag;
    }
}

class InputThread extends Thread {
    private Res res;

    public InputThread1(Res res) {
        this.res = res;
    }

    @Override
    public void run() {
        int count = 0;
        while (true) {
            synchronized (res) {
                if (res.getFlag()) {
                    try {
                        res.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                if (count == 0) {
                    res.setName("小紅");
                    res.setSex("女");
                } else {
                    res.setName("小軍");
                    res.setSex("男");
                }
                count = (count + 1) % 2;
                res.setFlag(true);
                res.notify();
            }
        }
    }
}

class OutputThread extends Thread {
    private Res res;

    public OutputThread1(Res res) {
        this.res = res;
    }

    @Override
    public void run() {
        while (true)
            synchronized (res) {
                if (!res.getFlag()) {
                    try {
                        res.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                System.out.println(res.getName() + "," + res.getSex());
                res.setFlag(false);
                res.notify();
            }
    }
}

public class Test002 {
    public static void main(String[] args) {
        Res res = new Res();
        res.setFlag(false);
        InputThread inputThread = new InputThread(res);
        OutputThread outputThread = new OutputThread(res);
        inputThread.start();
        outputThread.start();
    }
}

為什么在不能使用 this.wait() ?

因?yàn)樯厦鎰?chuàng)建的兩個(gè)線程分別是由兩個(gè)類創(chuàng)建的,它們的對(duì)象不同,所以所對(duì)象不同。

為什么 wait、notify 屬于 Object?

那是因?yàn)?wait、notify 需要使用到對(duì)象鎖,眾所周知,所有全局對(duì)象都可以作為對(duì)象鎖,而 Object 是所有對(duì)象的父類,只要在 Object 實(shí)現(xiàn)了 wait、notify,所有類都可以使用到

wait、notify

因?yàn)?wait、notify 使用的是對(duì)象鎖,所以它們必須放在 synchronize 中使用

wait 阻塞當(dāng)前執(zhí)行的線程

notify 喚醒鎖池中的線程,使之運(yùn)行

wait 與 join 的區(qū)別

wait 必須放置在 synchronize 中

join 不需要喚醒

wait 與 sleep 的區(qū)別

sleep 不需要放在 synchronize 中

sleep 不會(huì)釋放鎖

Lock 鎖

lock 寫法

Lock lock  = new ReentrantLock();
lock.lock();
try{
    //可能會(huì)出現(xiàn)線程安全的操作
} catch(異常){
    //處理異常
} finally{
    //一定在finally中釋放鎖
    //也不能把獲取鎖在try中進(jìn)行,因?yàn)橛锌赡茉讷@取鎖的時(shí)候拋出異常
    lock.unlock();
}

Lock 與 Synchronsize 的區(qū)別

Lock 可以非阻塞獲得鎖,當(dāng)前線程嘗試獲取鎖,如果鎖未被其他線程獲取,則成功獲得并持有鎖

Lock 接口能被中斷獲取鎖,獲取到鎖的線程能夠響應(yīng)中斷,當(dāng)獲取到的鎖的線程被中斷時(shí),中斷異常將會(huì)被拋出,同時(shí)鎖會(huì)被釋放

Lock 接口在指定的截止時(shí)間之前獲取鎖,如果截止時(shí)間到了依舊無(wú)法獲取鎖,則返回

Condition 用法

Condition 相當(dāng)于 wait 和 notify 的功能

Condition condition = lock.newCondition();
res. condition.await(); 類似wait
res. Condition. Signal() 類似notify

class Res  {
    private String name;
    private String sex;
    private Boolean flag;
    Lock lock = new ReentrantLock();

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public Boolean getFlag() {
        return flag;
    }

    public void setFlag(Boolean flag) {
        this.flag = flag;
    }
}

class InputThread extends Thread {
    private Res res;
    Condition condition;

    public InputThread (Res  res, Condition condition) {
        this.res = res;
        this.condition = condition;
    }

    @Override
    public void run() {
        int count = 0;
        while (true) {
            try {
                res.lock.lock();
                if (res.getFlag()) {
                    try {
                        res.wait();
                        condition.await();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                if (count == 0) {
                    res.setName("小紅");
                    res.setSex("女");
                } else {
                    res.setName("小軍");
                    res.setSex("男");
                }
                count = (count + 1) % 2;
                res.setFlag(true);
                condition.signal();
            } catch (Exception e) {

            } finally {
                res.lock.unlock();
            }
        }
    }
}

class OutputThread  extends Thread {
    private Res res;
    Condition condition;

    public OutputThread (Res res, Condition condition) {
        this.res = res;
        this.condition = condition;
    }

    @Override
    public void run() {
        try {
            res.lock.lock();
            while (true) {
                if (!res.getFlag()) {
                    try {
                        condition.await();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                System.out.println(res.getName() + "," + res.getSex());
                res.setFlag(false);
                condition.signal();
            }
        } catch (Exception e) {

        } finally {
            res.lock.unlock();
        }

    }
}

public class Test003 {
    public static void main(String[] args) {
        Res  res = new Res ();
        Condition condition = res.lock.newCondition();
        res.setFlag(false);
        InputThread inputThread = new InputThread(res, condition);
        OutputThread outputThread = new OutputThread(res, condition);
        inputThread.start();
        outputThread.start();
    }

}
向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI