Java多线程之线程协作

Wesley13
• 阅读 735

常见的线程协作方式是:生产者/消费者。

一个线程作为生产者,生产要处理数据,比如拿一个线程来生产Order,用户每下一单,此线程就生产一个Order对象。

设置一个仓库,来存放生产出来的Order对象。

一个线程作为消费者,消费|处理仓库中的Order对象(打印订单、拣货、发货)。


demo   订单处理流程

1、用一个类来封装要处理的数据

public class Order {
    private int id;
    //...

    public Order(int id) {
        this.id = id;
    }

    public int getId() {
        return id;
    }

    //......
}

2、仓库

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;

public class OrderStorage {
    //使用阻塞队列作为仓库
    private BlockingQueue<Order> queues;

    //默认仓库容量为50
    public OrderStorage() {
        this.queues = new LinkedBlockingQueue<>(50);
    }

    //初始化仓库容量
    public OrderStorage(int capacity) {
        this.queues = new LinkedBlockingQueue<>(capacity);
    }

    //入库
    public void push(Order order) throws InterruptedException {
        queues.put(order);
    }

    //出库
    public Order pop() throws InterruptedException {
        return queues.take();  //仓库中没元素时,会阻塞当前线程,直到有元素可弹出。要不怎么叫BlockingQueue
    }
}

java.util.concurrent包下有很多并发要使用的类,我们使用的阻塞队列就是这个包下的。concurrent  并发

队列是先进先出的,先生产的先放到仓库中,先处理。

3、生产者

public class ProducerThread extends Thread{
    public static OrderStorage orderStorage = new OrderStorage(100); //仓库容量为100

    @Override
    public void run() {
        int i=1;
        while (true){
            Order order = new Order(i);
            try {
                orderStorage.push(order); //放到仓库中
                System.out.println("已生产编号为"+i+"的订单");
                Thread.sleep(1000); //降低速度,方便看效果
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            i++;
        }
    }

}

容量为100,不是说只能生成50个Order,生产的同时消费者也在消费仓库中的Order。

4、消费者

public class ConsumerThread extends Thread {
    private OrderStorage orderStorage=ProducerThread.orderStorage; //消费者和生产者使用的要是同一个仓库

    @Override
    public void run() {
        while (true){
            try {
                Order order = orderStorage.pop(); //如果仓库中没有Order,会阻塞当前线程,直到有Order可以弹出
                System.out.println("已消费|处理编号为"+order.getId()+"的订单");
                Thread.sleep(1000); //降低速度,方便看效果
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

}

5、测试类

public class Test {
    public static void main(String[] args) {
        ProducerThread producerThread = new ProducerThread();
        producerThread.start();

        ConsumerThread consumerThread = new ConsumerThread();
        consumerThread.start();

    }
}

6、效果

Java多线程之线程协作

有时候一个订单,会先打印“消费”,再打印“生产”。

一个Order处理顺序一定是:生产 、入库  ->   出库、消费,要先放到仓库中才能从仓库中获取到。

只是说生产者、消费者2个线程执行sout时获取到时间片的先后不同。

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
待兔 待兔
5个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
捉虫大师 捉虫大师
3年前
一种极致性能的缓冲队列
本文已收录https://github.com/lkxiaolou/lkxiaolou欢迎star。背景在多线程下的生产者消费者模型中,需求满足如下情况:对生产者生产投递数据的性能要求非常高多个生产者,单个(多个也可以,本文只介绍单个的情况)消费者当消费者跟不上生产者速度时,可容忍少部分数据丢失生产者是单条单条地生产数据举个日志采集的例子,日志在不同的
九章 九章
3年前
一 java线程的等待/通知模型
java中线程之间的通信问题,有这么一个模型:一个线程修改了一个对象的值,而另一个线程感知到了变化,然后进行相应的操作,整个过程开始于一个线程,而最终执行又是另一个线程。前者是生产者,后者就是消费者,也可以叫做生产者消费者问题生产者生产了产品,如何通知消费者?下面就介绍下java线程中的等待通知机制。其它语言类似,自行研究。代码附上下面是以买小
Wesley13 Wesley13
3年前
4、jstack查看线程栈信息
1、介绍利用jps、top、jstack命令找到进程中耗时最大的线程,以及线程状态等等,同时最后还可以显示出死锁的线程查找:FoundoneJavaleveldeadlock即可1、jps获得进程号!(https://oscimg.oschina.net/oscnet/da00a309fa6
Wesley13 Wesley13
3年前
03.Android崩溃Crash库之ExceptionHandler分析
目录总结00.异常处理几个常用api01.UncaughtExceptionHandler02.Java线程处理异常分析03.Android中线程处理异常分析04.为何使用setDefaultUncaughtExceptionHandler前沿上一篇整体介绍了crash崩溃
Wesley13 Wesley13
3年前
Oracle一张表中实现对一个字段不同值和总值的统计(多个count)
需求:统计WAIT\_ORDER表中的工单总数、未处理工单总数、已完成工单总数、未完成工单总数。表结构:为了举例子方便,WAIT\_ORDER表只有两个字段,分别是ID、STATUS,其中STATUS为工单的状态。1表示未处理,2表示已完成,3表示未完成总数。 SQL:  1.SELECT   2
Wesley13 Wesley13
3年前
Java中生产者与消费者模式
 生产者消费者模式首先来了解什么是生产者消费者模式。该模式也称有限缓冲问题(英语:Boundedbufferproblem),是一个多线程同步问题的经典案例。该问题描述了两个共享固定大小缓冲区的线程——即所谓的“生产者”和“消费者”——在实际运行时会发生的问题。生产者的主要作用是生成一定量的数据放到缓冲区中,然后重复此过程。与此同
Wesley13 Wesley13
3年前
Java线程与多线程
1线程与多线程1.1线程是什么?线程(Thread)是一个对象(Object)。用来干什么?Java线程(也称JVM线程)是Java进程内允许多个同时进行的任务。该进程内并发的任务成为线程(Thread),一个进程里至少一个线程。Java程序采用多线程方式来支持大量的并发请求处理,程序如果在
Python进阶者 Python进阶者
11个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这