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

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JAVA 生产者和消费者Runnable实现,所有方法都放到对象里面,而非假店员之手相关的知识,希望对你有一定的参考价值。

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();

        }
    }
}

以上是关于JAVA 生产者和消费者Runnable实现,所有方法都放到对象里面,而非假店员之手的主要内容,如果未能解决你的问题,请参考以下文章

JAVA多线程之生产者和消费者案例

java生产者——消费者 线程模型

[Java] 多线程基础详细总结,附加详细实例

java并发编程--Executor框架

创建线程和synchronized关键字

Java 并发编程——Executor框架和线程池原理