JAVA 生产者和消费者Runnable实现,所有方法都放到对象里面,而非假店员之手

因为觉得把方法写到店员类里面,总是很怪异,不符合面向对象编程里面,谁的行为谁做。

package com.home.nxj.ProTest;

public class ProTest {
    public static void main(String[] args) {
        Clerk ck = new Clerk();
        Productors p1 = new Productors(ck);
        Concumers c1 = new Concumers(ck);

        Thread t1 = new Thread(p1);
        Thread t2 = new Thread(c1);

        t1.start();
        t2.start();
    }
}

//店员类,这里只提供一个产品信息。或者改为仓库类更合适
class Clerk{
    //里面只有一个属性,产品的剩余数字。protected,同包类可以访问
    protected int productCount = 0;
}

//用实现Runnable接口的方式,重写生产者消费者关系例子。
class Productors implements Runnable {
    //和店员类的联系属性
    private Clerk waiter;
    //带参构造器,实现和店员类,或者说仓库类的关联关系
    public Productors(Clerk waiter) {
        this.waiter = waiter;
    }
    //没啥好说的,Runnable接口实现后,重写run()方法。
    @Override
    public void run() {
        while (true) {
            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            //用synchrinized()函数来包装需要线程同步的代码。
            synchronized (waiter) {
                if (waiter.productCount < 20) {

                    waiter.productCount++;
                    System.out.println(Thread.currentThread().getName() + ":开始生产xx第" + waiter.productCount + "个产品");
                    //这里因为线程监控器不是this,所以不可以直接调用notify()。谁作为线程监控器,就由谁去调用notify()和wait()。
                    //notify();直接调用会报错:java.lang.IllegalMonitorStateException
                    waiter.notify();
                } else {
                    try {
                        waiter.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }
}

class Concumers implements Runnable {
    private Clerk waiter;

    public Concumers(Clerk waiter) {
        this.waiter = waiter;
    }

    @Override
    public void run() {
        while (true) {
            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            synchronized (waiter) {
                if (waiter.productCount > 0) {
                    System.out.println(Thread.currentThread().getName() + ":开始消费xx第" + waiter.productCount + "个产品");
                    waiter.productCount--;
                    waiter.notify();
                } else {
                    try {
                        waiter.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }
}

对比视频上看来的传统写法:

package com.home.nxj.ProductTest;

public class ProductTest {

    public static void main(String[] args) {
       Waiter waiter = new Waiter();
        Productor p1 = new Productor(waiter);
        p1.setName("生产者1");
        Customer c1 = new Customer(waiter);
        c1.setName("消费者");
        p1.start();
        c1.start();
    }

}

class Waiter{
    private int productCount = 0;
    //生产产品
    public synchronized void produceProduct() {
        if (productCount < 20){
            productCount ++;
            System.out.println(Thread.currentThread().getName() + ":开始生产第" + productCount +"个产品");

            notify();
        }else {
            //等待
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
    //消费产品
    public synchronized void consumeProduct() {
        if (productCount > 0){
            System.out.println(Thread.currentThread().getName() + ":开始消费" + productCount + "个产品");
            productCount --;
            notify();
        }else {
            //等待
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}
class Productor extends  Thread{
    private Waiter waiter;

    public Productor(Waiter waiter) {
        this.waiter = waiter;
    }

    @Override
    public void run() {
        System.out.println(getName() + ":开始生产产品" );
        while (true){
            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            waiter.produceProduct();
        }
    }
}
class Customer extends Thread{
    private Waiter waiter;

    public Customer(Waiter waiter) {
        this.waiter = waiter;
    }

    @Override
    public void run() {
        System.out.println(getName()+ ":开始消费...");
        while (true){
            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            waiter.consumeProduct();

        }
    }
}

原文地址:https://blog.51cto.com/accole/2480630

时间: 2024-08-03 00:40:39

JAVA 生产者和消费者Runnable实现,所有方法都放到对象里面,而非假店员之手的相关文章

java 生产者 与 消费者的案例

主要理解了两个问题 1.线程数据同步的问题 2.线程交替运行的方式 package ThreadDemo; /** * 生产者与消费者的案例(一,同步的问题,值的问题 二,交替执行的问题) * @author lile * 同步的问题(synchronized 知识点) * 交替执行的问题(notify ,wait, 线程等待) */public class ThreadDemo { public static void main(String[] args) { Food food = new

java 生产者与消费者问题

package concurrency; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class Storage { private int capacity; private int size; public Storage(int capacity){ this.capacity=capacity; size=0; } public synchronize

java 生产者和消费者

生产者和消费者的例子 一.wait() / notify()方法 wait() / nofity()方法是基类Object的两个方法,也就意味着所有Java类都会拥有这两个方法,这样,我们就可以为任何对象实现同步机制. wait()方法:当缓冲区已满/空时,生产者/消费者线程停止自己的执行,放弃锁,使自己处于等等状态,让其他线程执行. notify()方法:当生产者/消费者向缓冲区放入/取出一个产品时,向其他等待的线程发出可执行的通知,同时放弃锁,使自己处于等待状态. 直接贴上代码 用as cl

java 生产者与消费者初级探讨

最近学习java多线程有点迷糊,经过一天的整理,知道了什么是生产者,什么是消费者,以及消费者与生产者的关系: 在 Person类中是一个实体没有具体的对象,靠Input传入,Output读出,只有当Input有传入后,才能被Output读出,因此对呀Input和Output,要上一把同样的锁,synchronized将两个线程同步. wait(),notify(),notifyAll()都是继承至上帝类的:下面是生产者消费者的代码 //生产/消费者模式 public class Basket {

Java 生产者模式 消费者模式

1 // The standard idiom for calling the wait 2 synchronized(sharedObject) { 3 while(condition){ 4 sharedObject.wait();// Releases lock, and reacquires on wake up 5 } 6 // do action based upon condition e.g. take or put into queue 7 } 使用wait和notify函数的

java 生产者和消费者demo

1 package com.benq; 2 3 import java.util.*; 4 import java.util.concurrent.TimeUnit; 5 6 public class HH { 7 public static void main(String[] args){ 8 9 var store=new MyStore<Integer>(20); 10 11 for(int i=0;i<10;i++){ 12 var producer=new Procuder&

Java编程思想 4th 第2章 一切都是对象

Java是基于C++的,但Java是一种更纯粹的面向对象程序设计语言,和C++不同的是,Java只支持面向对象编程,因此Java的编程风格也是纯OOP风格的,即一切都是类,所有事情在类对象中完成. 在Java中,使用引用来操纵对象,在Java编程思想的第四版中,使用的术语是"引用(reference)",之前有读过Java编程思想第三版,在第三版中,使用的术语是"句柄(handle)",事实上,我觉得第三版的术语"句柄"更加形象传神,就像你用一个

《JAVA编程思想第四版》——一切都是对象

2.1 用句柄操纵对象 JAVA中一切都可"看做"对象.操作对象的方式是通过一个指向对象的句柄(又称引用或指针).但是句柄并不一定指向对象,此时操作句柄会获得一个错误(运行期) 比如:String s;s.length(); 这里创建句柄s,s并没有指向对象.如果此时向s发送一条消息会报错.编译器提示"the local variable s may not have been initialized" String s = new String("hel

Java线程同步模型-生产者与消费者

Java生产者与消费者模型是经典Java线程同步模型,涉及使用同步锁控制生产者线程和消费者线程同步运行问题.同步对象是仓库资源,生产者线程生产向仓库中生产商品,消费者线程从仓库中消费商品,当生产者线程生产的商品达到仓库的90%时,生产者线程停止生产并通知消费者线程开始消费,当消费者线程消耗到仓库的10%时,消费者线程停止消费并通知生产者线程恢复生产,如此循环往复过程. 如下图解: T1时刻分析 T2时刻 T3时刻 T4时刻 上图的分析,T3同T1时刻相同场景,T2同T2时刻相同场景,程序如此循环