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. 微信小程序把玩(三十一)wx.uploadFile(object), wx.downloadFile(object) API

    原文:微信小程序把玩(三十一)wx.uploadFile(object), wx.downloadFile(object) API 反正我是没有测通这两个API!!!!不知道用的方式不对还是其他的!! ...

  2. Xdite:永葆热情的上瘾式学习法(套路王:每天总结自己,反省自己的作息规律,找到自己的幸运时间、幸运方法,倒霉时间、倒霉方法。幸运是与注意力挂钩的。重复才能让自己登峰造极,主动去掉运气部分来训练自己。游戏吸引自己的几个原因非常适合训练自己)good

    版权声明 本文首发自微信公共帐号: 学习学习再学习(xiaolai-xuexi) 无需授权即可转载, 甚至无需保留以上版权声明: 转载时请务必注明作者. 以下是<共同成长社区>第 58 次 ...

  3. Android零基础入门第70节:ViewPager轻松完成TabHost效果

    上一期学习了ViewPager的简单使用,本期一起来学习ViewPager的更多用法. 相信很多同学都使用过今日头条APP吧,一打开主界面就可以看到顶部有很多Tab,然后通过左右滑动来切换,就可以通过 ...

  4. Qt使用windows API获取程序运行时占用内存 good

    使用的是psapi.h中的GetProcessMemoryInfo函数,但是运行到该函数时就强制退出了. 后来,百度到原因是 原来Qt编译时加了-mthread,createprocess时要使的Ha ...

  5. Qt for android触摸手势事件QGestureEvent

    在触摸设备上可以使用Qt的手势事件 要激活手势事件,需要执行以下操作: 第一步,为QWidget控件注册手势事件 QList<Qt::GestureType> gestures; gest ...

  6. 文件夹管理工具(MVC+zTree+layer)

    文件夹管理工具(MVC+zTree+layer)(附源码)   写在前 之前写了一篇关于 文件夹与文件的操作的文章  操作文件方法简单总结(File,Directory,StreamReader,St ...

  7. SYN1610型B码时统设备

       SYN1610型B码时统设备 产品概述 SYN1610型B码时统设备是由西安同步电子科技有限公司精心设计.自行研发生产的一款模块化配置的通用性时统终端,可接收北斗/ GPS信号/ IRIG-B码 ...

  8. python网络编程(转)

    本文代码转自廖雪峰老师的python教程 网络编程底层其实就是一个socket,代表两台机器之间的一个连接. s = socket.socket(socket.AF_INET, socket.SOCK ...

  9. python 方法无法在线程中使用(附python获取网络流量)

    在python中,定义一个方法,直接调用可以,但是创建一个线程来调用就可能导致失败.这种现象多出现在使用com对象进行系统操作时,而且是以线程的形式调用. 异常提示如下:syntax error.WM ...

  10. IOS 数据存储(NSKeyedArchiver 归档篇)

    什么是归档 当遇到有结构有组织的数据时,比如字典,数组,自定义的对象等在存储时需要转换为字节流NSData类型数据,再通过写入文件来进行存储. 归档的作用 之前将数据存储到本地,只能是字符串.数组.字 ...