多线程 - 生产者消费者问题

(一)生产者消费者问题:

  1.题目:

    采用Java 多线程技术,设计实现一个符合生产者和消费者问题的程序。 对一个对象(枪膛)进行操作,其最大容量是10颗子弹。 生产者线程是一个压入线程,它不断向枪膛中压入子弹;消费者线程是一个射出线程,它不断从枪膛中射出子弹。

  2.分析:

    这是个生产者与消费者问题,也是线程的同步问题, 为了防止执行个线程访问一个资源时出现忙等待,要使用的wait-notify函数,是两个线程交替执行。

  3.解题步骤:

    a.创建一个Factory类,包含Produce()方法和Consume()方法;

    b.创建一个Producer线程,模拟生产子弹;

    c.创建一个Consume线程,模拟消费子弹 ;

    d.创建一个测试类Demo.

  4.画图理解:

  5.扩展 - 线程安全问题

    (1)线程安全出现的原因:

      a.多线程的环境下;(单线程不会出现安全问题)

      b.多个线程拥有资源;

      c.对共享资源的操作不是原子性的。(原子性是指一次操作要么执行完,要么不执行)

    (2)那么怎么解决线程安全问题呢?

      答:使用同步代码块。

        格式:
                 sychronized (对象) {
                     要同步的代码块(你走我不走,我走你不走)
                 }

(二)代码体现:

  1.创建一个Factory类

public class Factory {
    String name;//加工厂名字
    int MAX_SIZE;//最多加工子弹数目 int size;//当前剩余子弹数 public Factory(String name, int MAX_SIZE) { this.name = name; this.MAX_SIZE = MAX_SIZE; } //使用同步方法,保证线程安全 public synchronized void produce(){ while (size >= MAX_SIZE){ try { //子弹充足,等待消费  wait(); } catch (InterruptedException e) { e.printStackTrace(); } } try { //加工子弹累了,休息会 Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } //生产了一颗子弹 size++; System.out.println("压入了一颗子弹,还剩下" + size + ""); //唤醒等待的所有线程  notifyAll(); } //使用同步方法,保证线程安全 public synchronized void consume(){ while (size <= 0){ try { //没有子弹了,等待  wait(); } catch (InterruptedException e) { e.printStackTrace(); } try { Thread.sleep(200);//射出子弹累了,休息会 } catch (InterruptedException e) { e.printStackTrace(); } } //射出了一颗子弹 size--; System.out.println("射出了一颗子弹,还剩下" + size + ""); //唤醒等待的所有线程  notifyAll(); } }
Factory

  2.创建一个Producer类实现Runnable接口

public class Producer implements Runnable {
    Factory factory;

    public Producer(Factory factory) {
        this.factory = factory; } @Override public void run() { //循环生产 while (true){ factory.produce(); } } }
Producer

  3.创建一个Consume类实现Runnable接口

public class Consumer implements Runnable{
    Factory factory;

    public Consumer(Factory factory) {
        this.factory = factory; } @Override public void run() { //循环消费 while (true){ factory.consume(); } } }
Consumer

  4.创建一个测试类Demo

public class Demo {
    public static void main(String[] args) { //创建一个加工厂 Factory factory = new Factory("子弹加工厂",200); //创建一个生产者对象和一个消费者对象 Producer producer = new Producer(factory); Consumer consumer = new Consumer(factory); //创建一个生产者线程和一个消费者线程 Thread t1 = new Thread(producer); Thread t2 = new Thread(consumer); //启动线程  t1.start(); t2.start(); } }
Demo

猜你喜欢

转载自www.cnblogs.com/bug-baba/p/10564498.html