首页 > 编程语言 > 详细

Java多线程 二 线程间通信

时间:2019-06-22 00:21:29      阅读:147      评论:0      收藏:0      [点我收藏+]

线程间通信:

多个线程在处理同一资源,但是

 

等待唤醒机制

涉及的方法:

1、wait() 让线程处于冻结状态,被wait的线程会被存储到线程池中。 

2、notify() 唤醒线程池中的一个线程(任意)

3、notifyAll() 唤醒线程池中的所有线程、、

这些方法都必须定义在同步中,

因为这些方法是用于操作线程状态的方法。

必须明确到底操作的那个锁上的线程。

 

为什么操作线程的方法wait notify notifyAll定义在了Object中。

因为这些方法是监视器方法,监视器其实就是锁。

锁可以是任意的对象,任意的对象调用的方法一定定义在Object类中。

package com.pzq.thread;

public class SyncDemo3 {

    public static void main(String[] args) {

        Resource resource = new Resource();
        Input input = new Input(resource);
        OutPut outPut = new OutPut(resource);
        Thread threadInput = new Thread(input);
        Thread threadOuput = new Thread(outPut);
        threadInput.start();
        threadOuput.start();
    }

}

class Input implements Runnable {

    Resource r;

    public Input(Resource r) {
        this.r = r;
    }

    @Override
    public void run() {
        int x = 0;
        while (true) {
            synchronized (r) {

                if (r.flag) {
                    try {
                        r.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                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;

    public OutPut(Resource r) {
        this.r = r;
    }

    @Override
    public void run() {
        while (true) {
            synchronized (r) {
                if (!r.flag) {
                    try {
                        r.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                System.out.println(r.name + "......" + r.sex);
                r.flag = false;
                r.notify();
            }
        }
    }

}

class Resource {
    String name;
    String sex;
    boolean flag = false;

    public Resource() {
    }

    public Resource(String name, String sex) {
        this.name = name;
        this.sex = sex;
    }
}

 

生产者消费者

代码优化,将同步方法封装到属性当中

package com.pzq.thread;

public class SyncDemo3 {

    public static void main(String[] args) {

        Resource resource = new Resource();
        Input input = new Input(resource);
        OutPut outPut = new OutPut(resource);
        Thread threadInput = new Thread(input);
        Thread threadOuput = new Thread(outPut);
        threadInput.start();
        threadOuput.start();
    }

}

class Input implements Runnable {

    Resource r;

    public Input(Resource r) {
        this.r = r;
    }

    @Override
    public void run() {
        int x = 0;
        while (true) {
            if (x == 0) {
                r.set("mike", "nan");
            } else {
                r.set("丽丽", "=========女");
            }
            x = (x + 1) % 2;
        }
    }

}

class OutPut implements Runnable {

    Resource r;

    public OutPut(Resource r) {
        this.r = r;
    }

    @Override
    public void run() {
        while (true) {
            r.out();
        }
    }

}

class Resource {
    private String name;
    private String sex;
    private boolean flag = false;

    public Resource() {
    }

    public synchronized void set(String name, String sex) {
        if (flag) {
            try {
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        this.name = name;
        this.sex = sex;
        flag = true;
        this.notify();
    }

    public synchronized void out() {
        if (!flag) {
            try {
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        System.out.println(this.name + "....." + this.sex);
        flag = false;
        this.notify();
    }

}

单生产单消费

package com.pzq.thread;

public class SyncDemo4 {

    public static void main(String[] args) {

        Resource2 resource = new Resource2();
        Producter input = new Producter(resource);
        Customer outPut = new Customer(resource);
        Thread threadInput = new Thread(input);
        Thread threadOuput = new Thread(outPut);
        threadInput.start();
        threadOuput.start();
    }

}

class Producter implements Runnable {

    Resource2 r;

    public Producter(Resource2 r) {
        this.r = r;
    }

    @Override
    public void run() {
        while (true) {
            r.set("烤鸭");
        }
    }

}

class Customer implements Runnable {

    Resource2 r;

    public Customer(Resource2 r) {
        this.r = r;
    }

    @Override
    public void run() {
        while (true) {
            r.out();
        }
    }

}

class Resource2 {
    private String name;
    private boolean flag = false;
    private int count = 1;

    public Resource2() {
    }

    public synchronized void set(String name) {
        if (flag) {
            try {
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        this.name = name + count;
        count++;
        System.out.println(Thread.currentThread().getName() + "生产者+++" + this.name);
        flag = true;
        this.notify();
    }

    public synchronized void out() {
        if (!flag) {
            try {
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        System.out.println(Thread.currentThread().getName() + "消费者" + "=================" + this.name);
        flag = false;
        this.notify();
    }

}

 

多生产者多消费者

if判断标记,只有一次,会导致不该运行的线程运行了。出现了数据错误的情况。

while判断标记,解决了线程获取执行权后,是否要运行

notify只能唤醒一个线程,如果本方唤醒了本方,就没有意义了。而且 while判断标记+notify会导致死锁。

notifyAll解决了,本方线程一定会唤醒对方线程。

package com.pzq.thread;

public class SyncDemo4 {

    public static void main(String[] args) {

        Resource2 resource = new Resource2();
        Producter input = new Producter(resource);
        Customer outPut = new Customer(resource);
        Thread threadInput1 = new Thread(input);
        Thread threadInput2 = new Thread(input);
        Thread threadInput3 = new Thread(input);
        Thread threadOuput1 = new Thread(outPut);
        Thread threadOuput2 = new Thread(outPut);
        Thread threadOuput3 = new Thread(outPut);
        Thread threadOuput4 = new Thread(outPut);
        Thread threadOuput5 = new Thread(outPut);
        threadInput1.start();
        threadInput2.start();
        threadInput3.start();
        threadOuput1.start();
        threadOuput2.start();
        threadOuput3.start();
        threadOuput4.start();
        threadOuput5.start();
    }

}

class Producter implements Runnable {

    Resource2 r;

    public Producter(Resource2 r) {
        this.r = r;
    }

    @Override
    public void run() {
        while (true) {
            r.set("烤鸭");
        }
    }

}

class Customer implements Runnable {

    Resource2 r;

    public Customer(Resource2 r) {
        this.r = r;
    }

    @Override
    public void run() {
        while (true) {
            r.out();
        }
    }

}

class Resource2 {
    private String name;
    private boolean flag = false;
    private int count = 1;

    public Resource2() {
    }

    public synchronized void set(String name) {
        while (flag) {
            try {
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        this.name = name + count;
        count++;
        System.out.println(Thread.currentThread().getName() + "生产者+++" + this.name);
        flag = true;
        this.notifyAll();
    }

    public synchronized void out() {
        while (!flag) {
            try {
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        System.out.println(Thread.currentThread().getName() + "消费者" + "=================" + this.name);
        flag = false;
        this.notifyAll();
    }

}

 

Java多线程 二 线程间通信

原文:https://www.cnblogs.com/qiangge-python/p/11067391.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!