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. 零元学Expression Blend 4 - Chapter 45 ListBox里的物件不能换行吗?

    原文:零元学Expression Blend 4 - Chapter 45 ListBox里的物件不能换行吗? ListBox里的排列不是垂直就是水平,觉得这样的排列很枯燥乏味吗? 想要它变聪明吗? ...

  2. C#应用配置信息保存和读取

    //保存信息 SystemConfig.WriteConfigData(“字段名称”, “这里是需要保存的内容”); //读取信息 SystemConfig.GetConfigData(“字段名称”, ...

  3. 简单的Windows Webcam应用:Barcode Reader

    原文:简单的Windows Webcam应用:Barcode Reader 在Windows上用WinForm创建一个Webcam应用需要用到DirectShow.DirectShow没有提供C#的接 ...

  4. Docker Explanation and Apache Image

    https://blog.sajjan.com.np/2017/02/05/docker-getting-started-containers-ubuntu/ https://blog.sajjan. ...

  5. Android和IOS启动第三方地图APP

    最近客户新提了需求,地址字段要能通过第三方的地图进行定位,于是对Android和IOS端进行了调整. 以下是调用地图部分的代码. android可按照包名来判断app是否存在: 方法: /* * ch ...

  6. SQL基础复习2

    一.视图 1.创建视图      创建视图后加 WITH CHECK OPTION 2.视图查询 数据库系统的处理方法: 视图消解法(View Resolution) 步骤: 进行有效性检查-> ...

  7. web.congfig 禁用 ViewState Session

    <!--禁用 ViewState Session--> <pages enableViewState="false" enableSessionState=&qu ...

  8. redis INFO 解释

    以一种易于解释(parse)且易于阅读的格式,返回关于 Redis 服务器的各种信息和统计数值. 通过给定可选的参数 section ,可以让命令只返回某一部分的信息: server 部分记录了 Re ...

  9. Libra 加密稳定币:Facebook的"野心"?

    2008年11月1日,有一个传说叫中本聪的日裔美国人,发表了一篇名为<比特币:一种点对点式的电子现金系统>的论文.2009年,比特币出世,从此开启了电子货币这个收割机器,全世界的韭菜都是一 ...

  10. selenium2 python 自动化测试实战

    自动化测试,一个现在被炒的火热的词:各大公司都在嚷嚷着要上自动化测试的项目,都在招聘各种自动化测试人员…非常荣幸的受作者邀请来帮忙写这个序,诚惶诚恐,何德何能?不记得何时开始认识的作者了.当初只是作为 ...