Java实现生产者与消费者的同步

在学习操作系统的时候,我们就接触了生产者与消费者,在Java多线程学习过程中、以及面试中也会常有涉及,在这里进行一下简单的总结。

首先,Java提供两种基本的多线程实现方式:

1、继承Thread类;2、实现Runnable接口;

另外:3、实现Callable<>接口,配合FutureTask类,用Thread类启动,Callable接口的call()方法带返回值(因为1和2线程执行是没有返回值的,所以出了这么个东东);

class Run implements Callable<String> {

    private String date = "xiaoma";

    @Override public String call() throws Exception {
        return date;
    }
}
public class RunTest {
    public static void main(String[] args) {
        Run run = new Run();
        FutureTask future = new FutureTask(run);
        future.run();
        try {
            System.out.println(future.get());
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
    }
}



采用继承Thread类方式:

- 1 优点:编写简单,如果需要访问当前线程,无需使用Thread.currentThread()方法,直接使用this,即可获得当前线程。
- 2 缺点:因为线程类已经继承了Thread类,所以不能再继承其他的父类。除此之外,继承Thread方式启动多线程不能够很好的体现数据共享。


采用实现Runnable接口方式:
- 1 优点: 线程类只是实现了Runnable接口,还可以继承其他的类。除此之外,线程对象可以同时被多个线程共享,所以非常适合多线程来处理同一份资源的情况,能够很好的体现数据共享。
- 2 缺点:编程稍微复杂,如果需要访问当前线程,必须使用Thread.currentThread()方法。


下面切入正题,Java实现生产者与消费者的同步,直接上代码:


1、操作对象

class Info {
    private String title;
    private String content;
    private boolean flag = true;// flag==true,表示可生产,不可消费。falg=false,表示可消费,不可生产。

    public synchronized void set(String title, String content) {
        if (this.flag == false) {
            try {
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        try {
            Thread.sleep(0);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        this.title = title;
        this.content = content;
        this.flag = false;
        this.notify();
    }

    public synchronized void get() {
        if (this.flag == true) {
            try {
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        try {
            Thread.sleep(0);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(this.title + " - " + this.content);
        this.flag = true;
        this.notify();
    }
}


2、生产者

class Producer implements Runnable {
    private Info info;

    public Producer(Info info) {
        this.info = info;
    }

    public void run() {
        for (int i = 0; i < 100; i++) {
            if (i % 2 == 0) {
                this.info.set("JAVA" + i, "最好的语言");
            } else {
                this.info.set("我有壶" + i, "你有酒吗?");
            }
        }
    }
}


3、消费者

class Customer implements Runnable {
    private Info info;

    public Customer(Info info) {
        this.info = info;
    }

    public void run() {
        for (int i = 0; i < 100; i++) {
            this.info.get();
        }
    }
}

4、测试类

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

大功告成,之所以用实现Runnable接口的方式实现是因为上面提到的:“数据共享”。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值