import java.util.Random;
import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.IntStream;

public class Test {
    public static void main(String[] args){
        ProductionChannelTest.test();
    }
}

abstract class InstructionBook{
    public final void create(){
        this.firstProcess();
        this.sedoncProcess();
    }

    protected abstract void firstProcess();
    protected abstract void sedoncProcess();
}

class Production extends InstructionBook{

    private final int prodID;

    public Production(int prodID) {
        this.prodID = prodID;
    }

    @Override
    protected void firstProcess() {
        System.out.println("execute the "+prodID+" first process");
    }

    @Override
    protected void sedoncProcess() {
        System.out.println("execute the "+prodID+" second process");
    }
}

class Worker extends Thread{
    private final ProductionChannel channel;

    private final static Random random = new Random(System.currentTimeMillis());

    public Worker(String name, ProductionChannel channel) {
        super(name);
        this.channel = channel;
    }

    @Override
    public void run() {
        while (true) {
            try{
                Production production = channel.takeProduction();
                System.out.println(getName()+" process the "+production);
                production.create();
                TimeUnit.SECONDS.sleep(random.nextInt(10));
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

class ProductionChannel{
    private final static int MAX_PROD = 100;
    private final Production[] productionQueue;

    private int tail;   //队列尾
    private int head;   //队列头
    private int total;  //当前流水有多少个待加工的产品

    private final Worker[] workers;

    public ProductionChannel(int workSize) {
        this.workers=new Worker[workSize];
        this.productionQueue=new Production[MAX_PROD];

        for (int i = 0; i < workSize; i++) {
            workers[i]=new Worker("Worker-"+i,this);
            workers[i].start();
        }
    }

    public void offerProduction(Production production){
        synchronized (this) {
            while (total >= productionQueue.length) {
                try{
                    this.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }

            productionQueue[tail]=production;
            tail=(tail+1)%productionQueue.length;
            total++;
            this.notifyAll();
        }
    }

    public Production takeProduction(){
        synchronized (this) {
            while (total <= 0) {
                try{
                    this.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }

        Production production = productionQueue[head];
        head = (head+1)%productionQueue.length;
        total--;
        this.notifyAll();;
        return production;
    }
}

class ProductionChannelTest{

    public static void test(){
        final ProductionChannel channel = new ProductionChannel(5);

        AtomicInteger productionNo = new AtomicInteger();

        IntStream.range(1,8).forEach(i->new Thread(()->{
            while(true){
                channel.offerProduction(new Production(productionNo.getAndIncrement()));

                try{
                    TimeUnit.SECONDS.sleep(ThreadLocalRandom.current().nextInt(10));
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            }).start());
    }
}

Worker-Thread设计模式的更多相关文章

  1. 多线程 Worker Thread 模式

    Worker是“工人”的意思,worker thread pattern中,工人线程(worker thread)会一次抓一件工作来处理,当没有工作可做时,工人线程会停下来等待心得工作过来. Work ...

  2. Worker Thread

    http://www.codeproject.com/Articles/552/Using-Worker-Threads Introduction Worker threads are an eleg ...

  3. Simple Worker Thread Class

    http://www.codeproject.com/Articles/36184/Simple-Worker-Thread-Class Introduction Many times we need ...

  4. 多线程系列之九:Worker Thread模式

    一,Worker Thread模式 也叫ThreadPool(线程池模式) 二,示例程序 情景:一个工作车间有多个工人处理请求,客户可以向车间添加请求.请求类:Request定义了请求的信息和处理该请 ...

  5. Exception thrown on Scheduler.Worker thread. Add `onError` handling

    <html> <head></head> <body> java.lang.IllegalStateException: Exception throw ...

  6. Scheduler & Task & Worker & Thread & Request & Session & Connection of SQL Server

    MSSQL一直以来被人们认为简单.好学,但等到大家掌握了入门操作,深入理解起来又觉得非常的“拧巴”,尤其是对用惯了Oracle的同学来说,究其根本原因,无非是MSSQL引入和暴露了太多的概念.细节和理 ...

  7. Do waiting or suspended tasks tie up a worker thread?

      https://blogs.msdn.microsoft.com/askjay/2012/07/29/do-waiting-or-suspended-tasks-tie-up-a-worker-t ...

  8. Mongodb之failed to create service entry worker thread

    Mongodb "failed to create service entry worker thread" 错误. 系统:CentOS release 6.8 mongod.lo ...

  9. Worker Thread模式

    工人线程Worker thread会逐个取回工作并进行处理,当所有工作全部完成后,工人线程会等待新的工作到来 5个工人线程从传送带取数据,3个传送工人线程将数据放入传送带 public class C ...

  10. Worker Thread等到工作来,来了就工作

    Worker是“工人”的意思,worker thread pattern中,工人线程(worker thread)会一次抓一件工作来处理,当没有工作可做时,工人线程会停下来等待心得工作过来. Work ...

随机推荐

  1. 微信小程序把玩(一)Hello WeApp

    原文:微信小程序把玩(一)Hello WeApp 本篇默认已经成功安装微信小程序工具 新建项目 AppID查看公众开发平台设置查看(https://mp.weixin.qq.com) 项目名称随意填写 ...

  2. 什么是AIFF?

    AIFF是音频交换文件格式(Audio Interchange File Format)的英文缩写,是Apple公司开发的一种声音文件格式,被Macintosh平台及其应用程序所支持,Netscape ...

  3. 笔记:Advanced Installer 打包Web应用

    原文:笔记:Advanced Installer 打包Web应用 公司要做一款增值税小产品,区别于ACME,本产品核心只有销项部分,面对的客户群是小企业,单税盒单开票机..... 我要做的主要有以下几 ...

  4. Android Studio 添加 Genymotion插件

    原文:Android Studio 添加 Genymotion插件 1.下载Genymotion:官网地址,必须先注册才能下载,下载带有VirtualBox的版本 2.安装:安装时会连VirtualB ...

  5. Android零基础入门第86节:探究Fragment生命周期

    一个Activity可以同时组合多个Fragment,一个Fragment也可被多个Activity 复用.Fragment可以响应自己的输入事件,并拥有自己的生命周期,但它们的生命周期直接被其所属的 ...

  6. C++没有库则寸步难行,有库则几乎可以做任何事情——Bjarne Stroustrupi

    "Without a good library, most interesting tasks are hard to do in C++; but given a good library ...

  7. 从Java和JavaScript来学习Haskell和Groovy

    直击现场 记得刚接触计算机的时候,我就受到了两个非常巨大的错误观念的影响,这个观念最初是来自于老师的传授还是学长的教诲已经记不清了,但是直到我工作几年以后,才慢慢有了实际的体会: 学习和使用什么编程语 ...

  8. BI-学习之 商业智能平台的引入(传统关系型数据库的问题)

    早在 SQL Server 2005里面就有了这种 完整的商业智能平台了,那时候Nosql什么的都还停留在概念性的提出阶段,发展至2009年才一下子蹦了出来变得众所周知了.当然这个要扯就扯远了,咱们还 ...

  9. qlineedit设置背景颜色(使用QPalette的方法不行,必须使用QSS)

    使用QPalette的方法不行, ui->le_text->setAutoFillBackground(true);qDebug() << ui->le_text-> ...

  10. Java NIO学习系列二:Channel

    上文总结了Java NIO中的Buffer相关知识点,本文中我们来总结一下它的好兄弟:Channel.上文有说到,Java NIO中的Buffer一般和Channel配对使用,NIO中的所有IO都起始 ...