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. IE的BHO通过IHTMLDocument2接口获得网页源代码

    参考了凤之焚的专栏:http://blog.csdn.net/lion_wing/article/details/769742 但是他的源码有些问题,即IHTMLElementCollection接口 ...

  2. 随机森林分类器(Random Forest)

    阅读目录 1 什么是随机森林? 2 随机森林的特点 3 随机森林的相关基础知识 4 随机森林的生成 5 袋外错误率(oob error) 6 随机森林工作原理解释的一个简单例子 7 随机森林的Pyth ...

  3. synchronized 专题

    这几天不断添加新内容,给个大概的提纲吧,方面朋友们阅读,各部分是用分割线隔开了的: synchronized与wait()/notify() JMM与synchronized ThreadLocal与 ...

  4. 向github提交本地项目

    首先你需要一个github账号,所有还没有的话先去注册吧! https://github.com/ 我们使用git需要先安装git工具,这里给出下载地址,下载后一路直接安装即可: https://gi ...

  5. C++/CLI 中使用 ref 和 out

    void fun(int^ % i){} // C# ref void fun([out]int^ % i) {} // C# out

  6. Qt实现长文件名(字符串)在QLabel中自适应缩短

    一.应用场景简述 当在有限宽度的QLable中显示很长的文件名/字符串时,超出QLabel宽度部分将不会显示,此时采取缩短文件名策略(也可实现为字符串滚动动画)可以缓解这一问题.在实现这一想法的过程中 ...

  7. 如何把zip文件直接解压到内存里?

    解压到硬盘再读进来耽误时间. var  LZip: TZipFile;  LMem: TMemoryStream;  LBytes: TBytes;begin  LZip := TZipFile.Cr ...

  8. 【Linux】Linux下跟踪记录每个用户对主机服务器进行的操作

    linux中跟踪每个用户对主机的操作,看有人之前已经写过如此shell,可直接参考,参考如下: 1.记录操作信息 这个脚本需添加至/etc/profile 脚本如下: history USER_IP= ...

  9. .net core 2.0 dbfirst 报 dotnet ef 未找到与命令“dotnet-ef”匹配的可执行文件的解决办法

    问题描述: 最近研究了一段时间.netcore dbfirst,新建类库用来生成实体模型,执行命令总是提示 未找到与命令“dotnet-ef”匹配的可执行文件,根据网上的解决办法引用 Microsof ...

  10. 如何在 cmd 命令行中查看、修改、删除与添加环境变量

    Windows 和 linux 区别 一.查看所有环境变量的名称和值:Linux下:exportWindows下:set二.根据名称查该环境变量的值:Linux下:echo $环境变量名比如:echo ...