线程间通讯

发布时间:2020-07-07 11:25:29 作者:灰白世界
来源:网络 阅读:351

什么是多线程通讯?

多线程通讯就是多个线程同时操作一个资源,但是操作的动作不同

代码实现

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() ?

因为上面创建的两个线程分别是由两个类创建的,它们的对象不同,所以所对象不同。

为什么 wait、notify 属于 Object?

那是因为 wait、notify 需要使用到对象锁,众所周知,所有全局对象都可以作为对象锁,而 Object 是所有对象的父类,只要在 Object 实现了 wait、notify,所有类都可以使用到

wait、notify

因为 wait、notify 使用的是对象锁,所以它们必须放在 synchronize 中使用

wait 阻塞当前执行的线程

notify 唤醒锁池中的线程,使之运行

wait 与 join 的区别

wait 必须放置在 synchronize 中

join 不需要唤醒

wait 与 sleep 的区别

sleep 不需要放在 synchronize 中

sleep 不会释放锁

Lock 锁

lock 写法

Lock lock  = new ReentrantLock();
lock.lock();
try{
    //可能会出现线程安全的操作
} catch(异常){
    //处理异常
} finally{
    //一定在finally中释放锁
    //也不能把获取锁在try中进行,因为有可能在获取锁的时候抛出异常
    lock.unlock();
}

Lock 与 Synchronsize 的区别

Lock 可以非阻塞获得锁,当前线程尝试获取锁,如果锁未被其他线程获取,则成功获得并持有锁

Lock 接口能被中断获取锁,获取到锁的线程能够响应中断,当获取到的锁的线程被中断时,中断异常将会被抛出,同时锁会被释放

Lock 接口在指定的截止时间之前获取锁,如果截止时间到了依旧无法获取锁,则返回

Condition 用法

Condition 相当于 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();
    }

}
推荐阅读:
  1. Vue入门七、父子组件间通讯
  2. 如何实现angular组件间通讯

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

并发 编程 线程间

上一篇:Keras模型转TensorFlow的案例

下一篇:Android游戏开发十日通(8)- Box2D的例子和学习小结

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》