资讯

精准传达 • 有效沟通

从品牌网站建设到网络营销策划,从策略到执行的一站式服务

线程间通讯

什么是多线程通讯?

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

成都创新互联长期为近千家客户提供的网站建设服务,团队从业经验10年,关注不同地域、不同群体,并针对不同对象提供差异化的产品和服务;打造开放共赢平台,与合作伙伴共同营造健康的互联网生态环境。为温县企业提供专业的网站设计制作、网站设计,温县网站改版等技术服务。拥有十年丰富建站经验和众多成功案例,为您定制开发。

代码实现

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();
    }

}

当前标题:线程间通讯
当前URL:http://cdkjz.cn/article/goojgh.html
多年建站经验

多一份参考,总有益处

联系快上网,免费获得专属《策划方案》及报价

咨询相关问题或预约面谈,可以通过以下方式与我们联系

大客户专线   成都:13518219792   座机:028-86922220