继续浏览精彩内容
慕课网APP
程序员的梦工厂
打开
继续
感谢您的支持,我会继续努力的
赞赏金额会直接到老师账户
将二维码发送给自己后长按识别
微信支付
支付宝支付

Java线程进阶:生产者——消费者问题。

摄氏du江
关注TA
已关注
手记 41
粉丝 58
获赞 1061
Java线程进阶:生产者——消费者问题。

生产者和消费者指的是两个不同线程类对象操作同一类资源的情况。

  • 生产者负责生产数据,消费者负责取走数据
  • 生产者每生产一组数据,消费者就要取走一组数据

  • 标准的生产者--消费者代码:
package cn.dujiang.demo;
class Info {
    private String title ; 
    private String content ;
    public void setTitle(String title){
        this.title = title ;
    }
    public String getTitle() {
        return title;
    }
    public String getContent() {
        return content;
    }
    public void setContent(String content) {
        this.content = content;
    }

}
class Productor implements Runnable {
    private Info info ;
    public Productor(Info info){
        this.info = info ;
    }
    @Override
    public void run() {
        for (int x = 0; x < 100 ; x++) {
            if (x % 2 == 0) {  //偶数
                this.info.setTitle("第1组数据");
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                this.info.setContent("1.数据说明");
            }else {
                this.info.setTitle("第2组数据");
                this.info.setContent("2.数据说明");
            }
        }
    }
}
class Customer implements Runnable {
    private Info info ;
    public  Customer(Info info) {
        this.info = info ;
    }
    @Override
    public void run() {
        for (int x = 0; x < 100; x++) {
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(this.info.getTitle() + "-" + this.info.getContent());

        }
    }
}
public class TestDemo {
    public static void main(String[] args) {
        Info info = new Info() ;
        new Thread(new Productor(info)).start();
        new Thread(new Customer(info)).start();

    }
}
/*
 * 以上的代码的运行结果:
第1组数据-2.数据说明
第1组数据-2.数据说明
第2组数据-2.数据说明
第2组数据-2.数据说明
第2组数据-2.数据说明....
|-数据错位,发现不再是一个所需要的完整数据;
|-数据重复取出,数据重复设置。*/
  • 解决了数据错乱的生产者--消费者问题
package cn.dujiang.demo;
class Info {
    private String title ; 
    private String content ;
    public synchronized void set(String title,String content){
        this.title = title ;
        try {
            Thread.sleep(200);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        this.content = content ;
    }
    public synchronized void get(){
        try {
            Thread.sleep(100);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(this.title + "-" + this.content);
    }
}
class Productor implements Runnable {
    private Info info ;
    public Productor(Info info){
        this.info = info ;
    }
    @Override
    public void run() {
        for (int x = 0; x < 100 ; x++) {
            if (x % 2 == 0) {  //偶数
                this.info.set("第1组数据","1.数据说明");
            }else {
                this.info.set("第2组数据","2.数据说明");

            }
        }
    }
}
class Customer implements Runnable {
    private Info info ;
    public  Customer(Info info) {
        this.info = info ;
    }
    @Override
    public void run() {
        for (int x = 0; x < 100; x++) {

            this.info.get();
        }
    }
}
public class TestDemo {
    public static void main(String[] args) {
        Info info = new Info() ;
        new Thread(new Productor(info)).start();
        new Thread(new Customer(info)).start();

    }
}
/*
 * 以上的代码的运行结果:
第1组数据-1.数据说明
第1组数据-1.数据说明
第2组数据-2.数据说明
第2组数据-2.数据说明
第2组数据-2.数据说明....
以上代码解决了数据错乱的问题,得到了很好的解决,但是,重复问题变得严重了
****************************************
*数据错位完全是因为非同步操作所造成的,所以应该使用同步处理。
*以为,取和设置是两个不同的操作
*/
  • 解决了线程重复的生产者消费者问题:
package cn.dujiang.demo;
class Info {
    private String title ; 
    private String content ;
    private boolean flag = true ;
    /*flag = true 表示可以生产,但是不可以取走
    flag = false 表示可以取走,但是不可以生产*/
    public synchronized void set(String title,String content){
        //重复进入到了set()方法里,发现不能够生产,所以要等待
        if (this.flag == false) {
            try {
                super.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        this.title = title ;
        try {
            Thread.sleep(200);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        this.content = content ;
        this.flag = false ; //修改生产标记
        super.notify(); //唤醒其他等待线程
    }
    public synchronized void get(){
        if (this.flag == true) {  //还没生产,继续等待
            try {
                super.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        try {
            Thread.sleep(100);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(this.title + "-" + this.content);
        this.flag = true ;
        super.notify();
    }
}
class Productor implements Runnable {
    private Info info ;
    public Productor(Info info){
        this.info = info ;
    }
    @Override
    public void run() {
        for (int x = 0; x < 100 ; x++) {
            if (x % 2 == 0) {  //偶数
                this.info.set("第1组数据","1.数据说明");
            }else {
                this.info.set("第2组数据","2.数据说明");

            }
        }
    }
}
class Customer implements Runnable {
    private Info info ;
    public  Customer(Info info) {
        this.info = info ;
    }
    @Override
    public void run() {
        for (int x = 0; x < 100; x++) {

            this.info.get();
        }
    }
}
public class TestDemo {
    public static void main(String[] args) {
        Info info = new Info() ;
        new Thread(new Productor(info)).start();
        new Thread(new Customer(info)).start();

    }
}
/*
 * 以上的代码的运行结果:
第1组数据-1.数据说明
第2组数据-2.数据说明
第1组数据-1.数据说明
第2组数据-2.数据说明
第1组数据-1.数据说明
第2组数据-2.数据说明....
生产者和消费者问题全部解决,但是执行会变慢,不过这就是经典的
生产者消费者问题
****************************************

*/

总结:以上便是经典的生产--消费线程同步问题的解决


℃江

打开App,阅读手记
10人推荐
发表评论
随时随地看视频慕课网APP