E-COM-NET
首页
在线工具
Layui镜像站
SUI文档
联系我们
hnzhangshilong
生产者与消费者
生产者消费者问题是研究多线程程序时绕不开的问题,它的描述是有一块生产者和消费者共享的有界缓冲区,生产者往缓冲区放入产品,消费者从缓冲区取走产品,这个过程可以无休止的执行,不能因缓冲区满生产者放不进产品而终止,也不能因缓冲区空消费者无产品可取而终止。
解决生产者消费者问题的方法有两种,一种是采用某种机制保持生产者和消费者之间的同步,一种是在生产者和消费者之间建立一个管道。前一种有较高的效率并且可控制性较好,比较常用,后一种由于管道缓冲区不易控制及被传输数据对象不易封装等原因,比较少用。
同步问题的核心在于,CPU是按时间片轮询的方式执行程序,我们无法知道某一个线程是否被执行、是否被抢占、是否结束等,因此生产者完全可能当缓冲区已满的时候还在放入产品,消费者也完全可能当缓冲区为空时还在取出产品。
现在同步问题的解决方法一般是采用信号或者加锁机制,即生产者线程当缓冲区已满时放弃自己的执行权,进入等待状态,并通知消费者线程执行。消费者线程当缓冲区已空时放弃自己的执行权,进入等待状态,并通知生产者线程执行。这样一来就保持了线程的同步,并避免了线程间互相等待而进入死锁状态。
JAVA
语言提供了独立于平台的线程机制,保持了”write once, run anywhere”的特色。同时也提供了对同步机制的良好支持。
在JAVA中,一共有四种方法支持同步,其中三个是同步方法,一个是管道方法。
1.
方法
wait()/notify
()
2.
方法
await()/signal()
3.
阻塞队列方法
BlockingQueue
4.
管道方法
PipedInputStream/PipedOutputStream
下面我们看各个方法的实现:
1.
方法
wait()/notify()
wait()和notify()是根类Object的两个方法,也就意味着所有的JAVA类都会具有这个两个方法,为什么会被这样设计呢?我们可以认为所有的对象默认都具有一个锁,虽然我们看不到,也没有办法直接操作,但它是存在的。
wait()方法表示:当缓冲区已满或空时,生产者或消费者线程停止自己的执行,放弃锁,使自己处于等待状态,让另一个线程开始执行;
notify()方法表示:当生产者或消费者对缓冲区放入或取出一个产品时,向另一个线程发出可执行通知,同时放弃锁,使自己处于等待状态。
下面是一个例子代码:
import
java.util.LinkedList;
public
class
Sycn1
{
private
LinkedList
<
Object
>
myList
=
new
LinkedList
<
Object
>
();
private
int
MAX
=
10
;
public
Sycn1()
{
}
public
void
start()
{
new
Producer().start();
new
Consumer().start();
}
public
static
void
main(String[] args)
throws
Exception
{
Sycn1 s1
=
new
Sycn1();
s1.start();
}
class
Producer
extends
Thread
{
public
void
run()
{
while
(
true
)
{
synchronized
(myList)
{
try
{
while
(myList.size()
==
MAX)
{
System.out.println(
"
warning: it's full!
"
);
myList.wait();
}
Object o
=
new
Object();
if
(myList.add(o))
{
System.out.println(
"
Producer:
"
+
o);
myList.notify();
}
}
catch
(InterruptedException ie)
{
System.out.println(
"
producer is interrupted!
"
);
}
}
}
}
}
class
Consumer
extends
Thread
{
public
void
run()
{
while
(
true
)
{
synchronized
(myList)
{
try
{
while
(myList.size()
==
0
)
{
System.out.println(
"
warning: it's empty!
"
);
myList.wait();
}
Object o
=
myList.removeLast();
System.out.println(
"
Consumer:
"
+
o);
myList.notify();
}
catch
(InterruptedException ie)
{
System.out.println(
"
consumer is interrupted!
"
);
}
}
}
}
}
}
2.
方法
await()/signal()
在JDK5.0以后,JAVA提供了新的更加健壮的线程处理机制,包括了同步、锁定、线程池等等,它们可以实现更小粒度上的控制。await()和signal()就是其中用来做同步的两种方法,它们的功能基本上和wait()/notify()相同,完全可以取代它们,但是它们和新引入的锁定机制Lock直接挂钩,具有更大的灵活性。
下面是一个例子代码:
import
java.util.LinkedList;
import
java.util.concurrent.locks.
*
;
public
class
Sycn2
{
private
LinkedList
<
Object
>
myList
=
new
LinkedList
<
Object
>
();
private
int
MAX
=
10
;
private
final
Lock lock
=
new
ReentrantLock();
private
final
Condition full
=
lock.newCondition();
private
final
Condition empty
=
lock.newCondition();
public
Sycn2()
{
}
public
void
start()
{
new
Producer().start();
new
Consumer().start();
}
public
static
void
main(String[] args)
throws
Exception
{
Sycn2 s2
=
new
Sycn2();
s2.start();
}
class
Producer
extends
Thread
{
public
void
run()
{
while
(
true
)
{
lock.lock();
try
{
while
(myList.size()
==
MAX)
{
System.out.println(
"
warning: it's full!
"
);
full.await();
}
Object o
=
new
Object();
if
(myList.add(o))
{
System.out.println(
"
Producer:
"
+
o);
empty.signal();
}
}
catch
(InterruptedException ie)
{
System.out.println(
"
producer is interrupted!
"
);
}
finally
{
lock.unlock();
}
}
}
}
class
Consumer
extends
Thread
{
public
void
run()
{
while
(
true
)
{
lock.lock();
try
{
while
(myList.size()
==
0
)
{
System.out.println(
"
warning: it's empty!
"
);
empty.await();
}
Object o
=
myList.removeLast();
System.out.println(
"
Consumer:
"
+
o);
full.signal();
}
catch
(InterruptedException ie)
{
System.out.println(
"
consumer is interrupted!
"
);
}
finally
{
lock.unlock();
}
}
}
}
}
3.
阻塞队列方法
BlockingQueue
BlockingQueue也是JDK5.0的一部分,它是一个已经在内部实现了同步的队列,实现方式采用的是我们的第2种await()/signal()方法。它可以在生成对象时指定容量大小。
它用于阻塞操作的是put()和take()方法。
put()方法类似于我们上面的生产者线程,容量最大时,自动阻塞。
take()方法类似于我们上面的消费者线程,容量为0时,自动阻塞。
下面是一个例子代码:
import
java.util.concurrent.
*
;
public
class
Sycn3
{
private
LinkedBlockingQueue
<
Object
>
queue
=
new
LinkedBlockingQueue
<
Object
>
(
10
);
private
int
MAX
=
10
;
public
Sycn3()
{
}
public
void
start()
{
new
Producer().start();
new
Consumer().start();
}
public
static
void
main(String[] args)
throws
Exception
{
Sycn3 s3
=
new
Sycn3();
s3.start();
}
class
Producer
extends
Thread
{
public
void
run()
{
while
(
true
)
{
//
synchronized(this){
try
{
if
(queue.size()
==
MAX)
System.out.println(
"
warning: it's full!
"
);
Object o
=
new
Object();
queue.put(o);
System.out.println(
"
Producer:
"
+
o);
}
catch
(InterruptedException e)
{
System.out.println(
"
producer is interrupted!
"
);
}
//
}
}
}
}
class
Consumer
extends
Thread
{
public
void
run()
{
while
(
true
)
{
//
synchronized(this){
try
{
if
(queue.size()
==
0
)
System.out.println(
"
warning: it's empty!
"
);
Object o
=
queue.take();
System.out.println(
"
Consumer:
"
+
o);
}
catch
(InterruptedException e)
{
System.out.println(
"
producer is interrupted!
"
);
}
//
}
}
}
}
}
你发现这个例子中的问题了吗?
如果没有,我建议你运行一下这段代码,仔细观察它的输出,是不是有下面这个样子的?为什么会这样呢?
…
warning: it's full!
Producer: java.lang.object@4526e2a
…
你可能会说这是因为put()和System.out.println()之间没有同步造成的,我也这样认为,我也这样认为,但是你把run()中的synchronized前面的注释去掉,重新编译运行,有改观吗?没有。为什么?
这是因为,当缓冲区已满,生产者在put()操作时,put()内部调用了await()方法,放弃了线程的执行,然后消费者线程执行,调用take()方法,take()内部调用了signal()方法,通知生产者线程可以执行,致使在消费者的println()还没运行的情况下生产者的println()先被执行,所以有了上面的输出。run()中的synchronized其实并没有起什么作用。
对于BlockingQueue大家可以放心使用,这可不是它的问题,只是在它和别的对象之间的同步有问题。
对于这种多重嵌套同步的问题,以后再谈吧,欢迎大家讨论啊!
4.
管道方法
PipedInputStream/PipedOutputStream
这个类位于java.io包中,是解决同步问题的最简单的办法,一个线程将数据写入管道,另一个线程从管道读取数据,这样便构成了一种生产者/消费者的缓冲区编程模式。
下面是一个例子代码,在这个代码我没有使用Object对象,而是简单的读写字节值,这是因为PipedInputStream/PipedOutputStream不允许传输对象,这是JAVA本身的一个bug,具体的大家可以看sun的解释: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4131126
import
java.io.
*
;
public
class
Sycn4
{
private
PipedOutputStream pos;
private
PipedInputStream pis;
//
private ObjectOutputStream oos;
//
private ObjectInputStream ois;
public
Sycn4()
{
try
{
pos
=
new
PipedOutputStream();
pis
=
new
PipedInputStream(pos);
//
oos = new ObjectOutputStream(pos);
//
ois = new ObjectInputStream(pis);
}
catch
(IOException e)
{
System.out.println(e);
}
}
public
void
start()
{
new
Producer().start();
new
Consumer().start();
}
public
static
void
main(String[] args)
throws
Exception
{
Sycn4 s4
=
new
Sycn4();
s4.start();
}
class
Producer
extends
Thread
{
public
void
run()
{
try
{
while
(
true
)
{
int
b
=
(
int
) (Math.random()
*
255
);
System.out.println(
"
Producer: a byte, the value is
"
+
b);
pos.write(b);
pos.flush();
//
Object o = new MyObject();
//
oos.writeObject(o);
//
oos.flush();
//
System.out.println("Producer: " + o);
}
}
catch
(Exception e)
{
//
System.out.println(e);
e.printStackTrace();
}
finally
{
try
{
pos.close();
pis.close();
//
oos.close();
//
ois.close();
}
catch
(IOException e)
{
System.out.println(e);
}
}
}
}
class
Consumer
extends
Thread
{
public
void
run()
{
try
{
while
(
true
)
{
int
b
=
pis.read();
System.out.println(
"
Consumer: a byte, the value is
"
+
String.valueOf(b));
//
Object o = ois.readObject();
//
if(o != null)
//
System.out.println("Consumer: " + o);
}
}
catch
(Exception e)
{
//
System.out.println(e);
e.printStackTrace();
}
finally
{
try
{
pos.close();
pis.close();
//
oos.close();
//
ois.close();
}
catch
(IOException e)
{
System.out.println(e);
}
}
}
}
//
class MyObject implements Serializable {
//
}
}
你可能感兴趣的:(生产者与消费者)
(王道408考研操作系统)第二章进程管理-第三节6:经典同步问题之生产者与消费者问题
快乐江湖
互斥
同步
操作系统
指导获取:密码7281专栏目录首页:【专栏必读】王道考研408计算机网络+湖科大教书匠计算机网络+网络编程万字笔记、题目题型总结、注意事项、目录导航和思维导图王道考研408计算机组成原理万字笔记王道考研408数据结构+计算机算法设计与分析万字笔记王道考研408计算机网络+湖科大教书匠计算机网络+网络编程万字笔记注意:生产者与消费者问题Linux系统编程专栏有案例讲解
Linux-使用阻塞队列实现生产者与消费者模型
风君子吖
Linux系统编程
linux
文章目录一、什么是生产者与消费者模型?二、示例模型示例模型介绍交易场所(blockQueue)消费者与生产者运行结果总结一、什么是生产者与消费者模型?参照日常生活中,购买商品的人群可以被称之为消费者,生产商品的工厂可以被称之为生产者,而在两者之间还存在超市被称之为交易场所。它们还存在三种关系,生产者与生产者之间是互斥关系,消费者与消费者之间也是互斥关系,消费者与生产者存在互斥/同步关系。这三种关系
Linux实现生产者消费者模型(基于阻塞队列)
roboko_
linux
c++
linux
目录概念及优势代码实现概念及优势生产者消费者模型是一种用于线程同步的模型,在这个模型中有两种角色,生产者生产数据,消费者消费数据。有三种关系,生产者与生产者,消费者与消费者,生产者与消费者。还有一个交易场所。超市就是生活中最常见的生产者消费者模型,工厂生产商品,超市充当缓冲区,消费者去超市消费同时取走超市中的商品。超市作为缓冲区,起到了很重要的作用,试想如果没有超市,那消费者想购物只能去找工厂,还
SpringBoot集成Pulsar 生产者与消费者示例代码
七维大脑
技术&解决方案分享
java
中间件
目录介绍功能特点一、导入pulsar依赖二、pulsar配置(示例为yml文件)三、生产者示例代码四、消费者代码介绍Pulsar是一个多租户、高性能的服务器到服务器消息传递解决方案。Pulsar最初由Yahoo开发,由Apache软件基金会管理。功能特点Pulsar的主要功能如下:原生支持Pulsar实例中的多个集群,并可跨集群无缝地复制消息。非常低的发布和端到端延迟。无缝扩展到超过一百万个主题。
Node.js 中使用 RabbitMQ
海上彼尚
node.js
node.js
rabbitmq
分布式
目录一、RabbitMQ简介二、核心概念解析三、环境搭建(以Ubuntu为例)四、Node.js实战:生产者与消费者1.安装依赖2.生产者代码(发送消息)3.消费者代码(处理消息)五、高级配置与最佳实践六、常见问题与解决方案七、总结一、RabbitMQ简介RabbitMQ是一个基于AMQP协议的开源消息代理工具,专为分布式系统设计。它通过解耦生产者和消费者实现异步通信,支持流量削峰、任务队列、服务
第十三章 Java多线程——阻塞队列
龙少丶
java
java
开发语言
13.1阻塞队列的由来我们假设一种场景,生产者一直生产资源,消费者一直消费资源,资源存储在一个缓存池中,生产者将生产的资源存进缓存池中,消费者从缓存池中拿到资源进行消费,这就是大名鼎鼎的生产者-消费者模式。该模式能够简化开发过程,一方面消除了生产者与消费者类之间的代码依赖性,另方面将生产数据的过程与使用数据的过程解耦简单化负载。我们⾃⼰coding实现这个模式的时候,因为需要让多个线程操作共享变量
Kafka 生产者与消费者的关系与应用场景分析
白.夜
kafka
json
在现代分布式系统中,ApacheKafka作为一个高性能的消息队列系统,在数据流转和处理方面扮演着至关重要的角色。Kafka采用了经典的生产者-消费者模式,极大地解耦了数据生成与数据消费的过程。本文将详细探讨Kafka中生产者与消费者的关系、常见问题以及Kafka在实际应用中的使用场景。1.Kafka中生产者与消费者的关系1.1生产者(Producer)生产者是Kafka系统中的一个客户端应用程序
RabbitMQ 补偿机制、消息幂等性解决方案
鸨哥学JAVA
Java
编程
程序员
java-rabbitmq
rabbitmq
java
1.场景先看这么几个面试题:如何保证消息的可靠性投递?即如何确定消息是否发送成功?如果失败如何处理(补偿机制)?如何保证消息不被重复消费?或者说,如何保证消息消费时的幂等性?2.消息的可靠性投递消息确认消息确认包括主要生产者发送确认和消费者接受确认,因为发送消息的过程中我们是无法确认消息是否能路由等,一旦消息丢失我们就无法处理,所以需要确认消息,避免消息丢失。2.1生产者确认我们知道生产者与消费者
RabbitMQ系列(零)概要
yyueshen
RabbitMQ
rabbitmq
分布式
消息队列
一、消息队列总览1.什么是消息队列?消息队列(MessageQueue)是一种异步通信机制,允许分布式系统中的服务通过生产-消费模型传递数据。其核心价值在于:解耦性:生产者与消费者无需同时在线或直接交互削峰填谷:应对流量突发场景,避免系统过载(如秒杀系统请求缓冲)可靠性:通过持久化、重试机制保障消息不丢失2.典型应用场景场景实现原理案例服务异步化耗时操作异步执行(如日志记录)用户注册后异步发送通知
RocketMQ(一):消息中间件缘起,一览整体架构及核心组件
菜菜的后端私房菜
消息中间件
rocketmq
架构
RocketMQ(一):消息中间件缘起,一览整体架构及核心组件消息队列MessageQueue,简称MQ在队列的基础上,加入生产者与消费者模型,使用队列作为载体就能够组成简单的消息队列,在队列中“运输”的数据被称为消息消息队列可以在单节点内存中使用,也可以作为分布式存储的中间件来使用由于项目的架构组织,目前常接触的消息队列往往是作为分布式存储的消息中间件来使用,比如:RabbitMQ、Rocket
简识MQ之Kafka、ActiveMQ、RabbitMQ、RocketMQ传递机制
天天向上杰
MQ
kafka
activemq
rabbitmq
rocketmq
四种主流消息队列(Kafka、ActiveMQ、RabbitMQ、RocketMQ)的生产者与消费者传递信息的机制说明,以及实际使用中的注意事项和示例:1.ApacheKafka传递机制模型:基于发布-订阅模型,生产者向主题(Topic)发送消息,消费者订阅主题并消费消息。核心流程:生产者将消息发送到Kafka集群的Broker,根据分区策略(如轮询、哈希)将消息写入对应的分区(Partition
头歌实训 第1关:生产者与消费者问题
Shadow10260530
linux
ubuntu
头歌实训第1关:生产者与消费者问题任务描述本关任务:程序4-1.c模拟了1个生产者和1个消费者,请改写该程序,模拟5个生产者和5个消费者,它们共享一个包含8个缓冲区的缓冲池。产品以4位编号,最高位表示生产者编号、其他表示该生产者的产品号,参考输出如下:知识多线程程序如何编译输入gcc-pthreadXX.c,编译成功后输入./a.out。pthread_create()函数原型intpthread
Kafka 设计之生产者与消费者
流华追梦
Kafka
kafka
生产者设计
负载均衡
异步发送
消费者设计
推送和拉取
离线数据加载
目录一.前言二.生产者设计2.1.负载均衡(Loadbalancing)2.2.异步发送(Asynchronoussend)三.消费者设计3.1.推送(Push)vs拉取(Pull)3.2.消费者定位(ConsumerPosition)3.3.离线数据加载(OfflineDataLoad)3.4.静态成员身份(StaticMembership)一.前言接上一篇《Kafka设计之效率》。本文将介绍K
大数据框架之kafka详解
xingchensuiyue
大数据
zookeeper
kafka
kafka
目录1kafka介绍1.1kalka是什么?1.2Kafka内部原理1.3为什么需要消息队列?2Kafka的消息系统语义3Kafka生产过程分析3.1写入方式3.2分区(Partition)3.3副本(Replication)3.4Producer写入流程3.5消费者组3.6消费方式扩展:纠删码技术1kafka介绍1.1kalka是什么?可以简单的将kafka看做是一种消息队列,启动生产者与消费者
RabbitMQ 入门教程
寂然如故
RabbitMQ
ruby
开发语言
后端
概述RabbitMQ是一个开源的消息代理和队列服务器,实现了高级消息队列协议(AMQP)。它能够接收、存储和转发消息数据。本教程将引导你完成搭建RabbitMQ环境、编写生产者与消费者程序的过程。安装与配置1.安装RabbitMQLinux```bashsudoapt-getupdatesudoapt-getinstallrabbitmq-server```Windows-下载安装包:https:
【Go - 模式示例 - 5分钟写个 生产者/消费者 】
wn531
golang
开发语言
后端
今天写个经典模式生成者-消费者,开始之前简单梳理下,这个模式需要注意什么,生产者-消费者之间的桥梁,生产者与消费者同进程,使用Go中的channel作为通信的桥梁,也可以说channel是个消息队列。生产者与消费者跨进程,需要使用一个消息队列服务,比如rabbitMQ,kafka等来进行通信。考虑多协程,Go中一般不会用线程,而是协程,在多协程的情况下,要考虑同时写,造成写覆盖的情况。废话不多说,
你是生产者,还是消费者?
水手成长日记
公众号:水手成长日记-地位-Identity你是生产者还是消费者?社会中的人有两种身份:生产者和消费者。生产者是创造价值的,消费者是消耗价值的。生产者与消费者谁优谁劣?其实两者没有优劣之分,因为缺了谁都不行。没有生产者产出价值,消费者就无从消费。没有消费者消化产值,生产者的工作也是徒劳。而且几乎每个人都会是双重身份。但是双重身份不代表每个人的产出和消费是对等。有人是产出10块钱的价值,消费1块钱的
Rabbitmq入门与应用(二)-RabbitMQ工作模型
自信人间三百年
rabbitmq
rabbitmq
ruby
分布式
RabbitMQ工作模型RabbitMQTutorials—RabbitMQBrokerRabbitMQ服务。Connection生产者或是服务者都需要与Broker建立的TCP连接。Channel保持的TCP长连接里面去创建和释放Channel,从而减少资源的消耗。其中Channel是相互隔离的,不能共享。QueueQueue是生产者与消费者的中间交互队列,生产者发送的消息到达队列,在队列中存储
28. OP-TEE驱动篇----tee_supplicant接口在驱动中的实现
漂流的猴子
OP-TEE
ARM
TrustZone技术
OP-TEE
tee_supplicant
optee驱动
CA
driver
在《22.OP-TEE中TA与CA执行流程-------tee-supplicant(一)》一文中介绍了tee_supplicant主要作用,用来实现secureworld端操作REE侧文件系统,EMMC的rpmb分区,网络socket操作,数据库操作的需求。tee_supplicant与secureworld之间的交互模式类似于生产者与消费者的方式进行配合来是实现上述需求。完成上述需求的整个过程
多进程、多线程、生成器实现生产者消费者模型
caelansar
多线程实现多线程实现生产者消费者模型的逻辑十分简单,生产者与消费者之间通过队列来进行通讯,所以生产者不用等待消费者消费,直接丢给队列,同理,消费者也是一样,不用通过生产者取得数据,而是从队列里面拿取数据。这样,队列就相当于一个缓冲区,一个容器,平衡生产者与消费者的处理能力:importrandomfromthreadingimportThreadfromqueueimportQueueclassP
Java并发基础:LinkedBlockingDeque全面解析!
程序员古德
Java并发基础
java
网络
网络协议
内容概要LinkedBlockingDeque提供了线程安全的双端队列实现,它支持在队列两端高效地进行插入和移除操作,同时具备阻塞功能,能够很好地协调生产者与消费者之间的速度差异,其内部基于链表结构,使得并发性能优异,是处理多线程间数据传递的理想选择。核心概念LinkedBlockingDeque实现了一个线程安全的双端队列(Deque,即double-endedqueue),这个队列在两端都可以
JUC:生产者消费者模式
ZRJ0618
JUC
java
多线程
文章目录虚假唤醒(spuriouswakeup)生产者与消费者模板生产者与消费者模式:synchronized虚假唤醒(spuriouswakeup)当需要条件判断使用wait()方法时,应该使用循环,而不是if,否则就可能会出现虚假唤醒(spuriouswakeup)的情况简单点理解,虚假唤醒就是除了理应被唤醒的线程之外,还另外唤醒了其它的线程,导致的数据的错误虚假唤醒的原理:例:publicc
JUC多线程编程之生产者与消费者问题(Synchronized和JUC版)
不会编程的派大星
JUC并发编程
java
多线程
并发编程
juc
锁
生产者与消费者问题在面试中,生产者与消费者是高频问题之一1.生产者和消费者问题Synchronized版publicclassA{publicstaticvoidmain(String[]args){Datadata=newData();newThread(()->{for(inti=0;i{for(inti=0;i{for(inti=0;i{for(inti=0;i"+number);//通知其
多线程下的生产者与消费者模式及(notify()与signal()唤醒的使用和区别)
若曦`
java
多线程
多线程
并发编程
java
生产者与消费者
Lock
1.问题的起源2.传统的解决方案(1)if()造成的虚假唤醒问题(2)生产消费问题的解决①synchronized+wait()+notify()为什么不用sleep()?②Lock+Condition3.notify()到底唤醒的是谁?4.Condition的精准唤醒5.notify()与signal()唤醒的区别1.问题的起源用现实中的快餐店:生产一个汉堡消费一个汉堡为例代码示例//多线程下的
多线程 生产者与消费者 遇到的问题以及解决方法
小白鼠丶
多线程
JUC
多线程
生产者消费者
目录最原始的生产者消费者模型问题一:产品product>=1时wait问题二:增加一些消费者和生产者线程最原始的生产者消费者模型packagecom.juc;/**生产者和消费者案例*/publicclassTestProductorAndConsumer1{publicstaticvoidmain(String[]args){Clerkclerk=newClerk();Productorpro=
JUC编程02:生产者与消费者问题
微笑AJJD
JUC编程
生产者与消费者问题
并发问题
锁
多线程
一、Synchronized解决方案代码演示packagecom.haust.pc;/***线程之间的通信问题:生产者和消费者问题!等待唤醒,通知唤醒*线程交替执行AB操作同一个变量num=0*Anum+1*Bnum-1*/publicclassA{publicstaticvoidmain(String[]args){Datadata=newData();newThread(()->{for(in
kafka生产者与消费者
代码人的自白
Hadoop大数据技术
kafka生产与消费
启动:./kafka-server-start.sh../config/server.properties创建topic./kafka-topics.sh–create–zookeeperlocalhost:2182–replication-factor1–partitions1–topicmytopic查看topic./kafka-topics.sh–list–zookeeperlocalhos
SpringCloud-REST实现生产者与消费者的通信服务
CryFace
环境搭建我们需要创建一个普通的maven项目就行,因为后面我们的服务将会以模块在里面创建。同时我们将src目录删除,因为我们不会用到这个目录。然后就是导入SpringCloud的依赖,同时要导入SpringBoot的依赖,我们之前说过,二者是有依赖关系的。要注意的SpringCloud的版本号所兼容的SpringBoot,这里可以去官网查询。这是目前比较新的官网查询地址:https://sprin
4:RocketMq实战(生产者与消费者 各种实战)(常见)(文末有项目连接)
_River_
目录1:服务器配置文件核心配置config2:生产者核心配置(Java代码)3:消费者核心配置(Java代码)4:RocketMQ消息常见发送状态5:集群和广播模式下RocketMQ消费端处理1:服务器配置文件核心配置confignamesrvAddr:该节点所在集群地址(192.168.159.129:9876;192.168.159.130:9876)brokerClusterName:集群名
kafka生产者与消费者
Ryan成长笔记
kafka
linq
分布式
文章目录一、pom.xml依赖包二、yml配置文件三、消费者四、生产者总结提示:这里可以添加本文要记录的大概内容:一、pom.xml依赖包org.springframework.kafkaspring-kafka2.8.0二、yml配置文件spring:kafka:listener:concurrency:3#线程数ack-mode:manual_immediatetype:batch#批量boo
继之前的线程循环加到窗口中运行
3213213333332132
java
thread
JFrame
JPanel
之前写了有关java线程的循环执行和结束,因为想制作成exe文件,想把执行的效果加到窗口上,所以就结合了JFrame和JPanel写了这个程序,这里直接贴出代码,在窗口上运行的效果下面有附图。 package thread; import java.awt.Graphics; import java.text.SimpleDateFormat; import java.util
linux 常用命令
BlueSkator
linux
命令
1.grep 相信这个命令可以说是大家最常用的命令之一了。尤其是查询生产环境的日志,这个命令绝对是必不可少的。 但之前总是习惯于使用 (grep -n 关键字 文件名 )查出关键字以及该关键字所在的行数,然后再用 (sed -n '100,200p' 文件名),去查出该关键字之后的日志内容。 但其实还有更简便的办法,就是用(grep -B n、-A n、-C n 关键
php heredoc原文档和nowdoc语法
dcj3sjt126com
PHP
heredoc
nowdoc
<!doctype html> <html lang="en"> <head> <meta charset="utf-8"> <title>Current To-Do List</title> </head> <body> <?
overflow的属性
周华华
JavaScript
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml&q
《我所了解的Java》——总体目录
g21121
java
准备用一年左右时间写一个系列的文章《我所了解的Java》,目录及内容会不断完善及调整。 在编写相关内容时难免出现笔误、代码无法执行、名词理解错误等,请大家及时指出,我会第一时间更正。 &n
[简单]docx4j常用方法小结
53873039oycg
docx
本代码基于docx4j-3.2.0,在office word 2007上测试通过。代码如下: import java.io.File; import java.io.FileInputStream; import ja
Spring配置学习
云端月影
spring配置
首先来看一个标准的Spring配置文件 applicationContext.xml <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi=&q
Java新手入门的30个基本概念三
aijuans
java
新手
java 入门
17.Java中的每一个类都是从Object类扩展而来的。 18.object类中的equal和toString方法。 equal用于测试一个对象是否同另一个对象相等。 toString返回一个代表该对象的字符串,几乎每一个类都会重载该方法,以便返回当前状态的正确表示.(toString 方法是一个很重要的方法) 19.通用编程:任何类类型的所有值都可以同object类性的变量来代替。
《2008 IBM Rational 软件开发高峰论坛会议》小记
antonyup_2006
软件测试
敏捷开发
项目管理
IBM
活动
我一直想写些总结,用于交流和备忘,然都没提笔,今以一篇参加活动的感受小记开个头,呵呵! 其实参加《2008 IBM Rational 软件开发高峰论坛会议》是9月4号,那天刚好调休.但接着项目颇为忙,所以今天在中秋佳节的假期里整理了下. 参加这次活动是一个朋友给的一个邀请书,才知道有这样的一个活动,虽然现在项目暂时没用到IBM的解决方案,但觉的参与这样一个活动可以拓宽下视野和相关知识.
PL/SQL的过程编程,异常,声明变量,PL/SQL块
百合不是茶
PL/SQL的过程编程
异常
PL/SQL块
声明变量
PL/SQL; 过程; 符号; 变量; PL/SQL块; 输出; 异常; PL/SQL 是过程语言(Procedural Language)与结构化查询语言(SQL)结合而成的编程语言PL/SQL 是对 SQL 的扩展,sql的执行时每次都要写操作
Mockito(三)--完整功能介绍
bijian1013
持续集成
mockito
单元测试
mockito官网:http://code.google.com/p/mockito/,打开documentation可以看到官方最新的文档资料。 一.使用mockito验证行为 //首先要import Mockito import static org.mockito.Mockito.*; //mo
精通Oracle10编程SQL(8)使用复合数据类型
bijian1013
oracle
数据库
plsql
/* *使用复合数据类型 */ --PL/SQL记录 --定义PL/SQL记录 --自定义PL/SQL记录 DECLARE TYPE emp_record_type IS RECORD( name emp.ename%TYPE, salary emp.sal%TYPE, dno emp.deptno%TYPE ); emp_
【Linux常用命令一】grep命令
bit1129
Linux常用命令
grep命令格式 grep [option] pattern [file-list] grep命令用于在指定的文件(一个或者多个,file-list)中查找包含模式串(pattern)的行,[option]用于控制grep命令的查找方式。 pattern可以是普通字符串,也可以是正则表达式,当查找的字符串包含正则表达式字符或者特
mybatis3入门学习笔记
白糖_
sql
ibatis
qq
jdbc
配置管理
MyBatis 的前身就是iBatis,是一个数据持久层(ORM)框架。 MyBatis 是支持普通 SQL 查询,存储过程和高级映射的优秀持久层框架。MyBatis对JDBC进行了一次很浅的封装。 以前也学过iBatis,因为MyBatis是iBatis的升级版本,最初以为改动应该不大,实际结果是MyBatis对配置文件进行了一些大的改动,使整个框架更加方便人性化。
Linux 命令神器:lsof 入门
ronin47
lsof
lsof是系统管理/安全的尤伯工具。我大多数时候用它来从系统获得与网络连接相关的信息,但那只是这个强大而又鲜为人知的应用的第一步。将这个工具称之为lsof真实名副其实,因为它是指“列出打开文件(lists openfiles)”。而有一点要切记,在Unix中一切(包括网络套接口)都是文件。 有趣的是,lsof也是有着最多
java实现两个大数相加,可能存在溢出。
bylijinnan
java实现
import java.math.BigInteger; import java.util.regex.Matcher; import java.util.regex.Pattern; public class BigIntegerAddition { /** * 题目:java实现两个大数相加,可能存在溢出。 * 如123456789 + 987654321
Kettle学习资料分享,附大神用Kettle的一套流程完成对整个数据库迁移方法
Kai_Ge
Kettle
Kettle学习资料分享 Kettle 3.2 使用说明书 目录 概述..........................................................................................................................................7 1.Kettle 资源库管
[货币与金融]钢之炼金术士
comsci
金融
自古以来,都有一些人在从事炼金术的工作.........但是很少有成功的 那么随着人类在理论物理和工程物理上面取得的一些突破性进展...... 炼金术这个古老
Toast原来也可以多样化
dai_lm
android
toast
Style 1: 默认 Toast def = Toast.makeText(this, "default", Toast.LENGTH_SHORT); def.show(); Style 2: 顶部显示 Toast top = Toast.makeText(this, "top", Toast.LENGTH_SHORT); t
java数据计算的几种解决方法3
datamachine
java
hadoop
ibatis
r-langue
r
4、iBatis 简单敏捷因此强大的数据计算层。和Hibernate不同,它鼓励写SQL,所以学习成本最低。同时它用最小的代价实现了计算脚本和JAVA代码的解耦,只用20%的代价就实现了hibernate 80%的功能,没实现的20%是计算脚本和数据库的解耦。 复杂计算环境是它的弱项,比如:分布式计算、复杂计算、非数据
向网页中插入透明Flash的方法和技巧
dcj3sjt126com
html
Web
Flash
将 Flash 作品插入网页的时候,我们有时候会需要将它设为透明,有时候我们需要在Flash的背面插入一些漂亮的图片,搭配出漂亮的效果……下面我们介绍一些将Flash插入网页中的一些透明的设置技巧。 一、Swf透明、无坐标控制 首先教大家最简单的插入Flash的代码,透明,无坐标控制: 注意wmode="transparent"是控制Flash是否透明
ios UICollectionView的使用
dcj3sjt126com
UICollectionView的使用有两种方法,一种是继承UICollectionViewController,这个Controller会自带一个UICollectionView;另外一种是作为一个视图放在普通的UIViewController里面。 个人更喜欢第二种。下面采用第二种方式简单介绍一下UICollectionView的使用。 1.UIViewController实现委托,代码如
Eos平台java公共逻辑
蕃薯耀
Eos平台java公共逻辑
Eos平台
java公共逻辑
Eos平台java公共逻辑 >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 蕃薯耀 2015年6月1日 17:20:4
SpringMVC4零配置--Web上下文配置【MvcConfig】
hanqunfeng
springmvc4
与SpringSecurity的配置类似,spring同样为我们提供了一个实现类WebMvcConfigurationSupport和一个注解@EnableWebMvc以帮助我们减少bean的声明。 applicationContext-MvcConfig.xml <!-- 启用注解,并定义组件查找规则 ,mvc层只负责扫描@Controller --> <
解决ie和其他浏览器poi下载excel文件名乱码
jackyrong
Excel
使用poi,做传统的excel导出,然后想在浏览器中,让用户选择另存为,保存用户下载的xls文件,这个时候,可能的是在ie下出现乱码(ie,9,10,11),但在firefox,chrome下没乱码, 因此必须综合判断,编写一个工具类: /** * * @Title: pro
挥洒泪水的青春
lampcy
编程
生活
程序员
2015年2月28日,我辞职了,离开了相处一年的触控,转过身--挥洒掉泪水,毅然来到了兄弟连,背负着许多的不解、质疑——”你一个零基础、脑子又不聪明的人,还敢跨行业,选择Unity3D?“,”真是不自量力••••••“,”真是初生牛犊不怕虎•••••“,••••••我只是淡淡一笑,拎着行李----坐上了通向挥洒泪水的青春之地——兄弟连! 这就是我青春的分割线,不后悔,只会去用泪水浇灌——已经来到
稳增长之中国股市两点意见-----严控做空,建立涨跌停版停牌重组机制
nannan408
对于股市,我们国家的监管还是有点拼的,但始终拼不过飞流直下的恐慌,为什么呢? 笔者首先支持股市的监管。对于股市越管越荡的现象,笔者认为首先是做空力量超过了股市自身的升力,并且对于跌停停牌重组的快速反应还没建立好,上市公司对于股价下跌没有很好的利好支撑。 我们来看美国和香港是怎么应对股灾的。美国是靠禁止重要股票做空,在
动态设置iframe高度(iframe高度自适应)
Rainbow702
JavaScript
iframe
contentDocument
高度自适应
局部刷新
如果需要对画面中的部分区域作局部刷新,大家可能都会想到使用ajax。 但有些情况下,须使用在页面中嵌入一个iframe来作局部刷新。 对于使用iframe的情况,发现有一个问题,就是iframe中的页面的高度可能会很高,但是外面页面并不会被iframe内部页面给撑开,如下面的结构: <div id="content"> <div id=&quo
用Rapael做图表
tntxia
rap
function drawReport(paper,attr,data){ var width = attr.width; var height = attr.height; var max = 0; &nbs
HTML5 bootstrap2网页兼容(支持IE10以下)
xiaoluode
html5
bootstrap
<!DOCTYPE html> <html> <head lang="zh-CN"> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge">
按字母分类:
A
B
C
D
E
F
G
H
I
J
K
L
M
N
O
P
Q
R
S
T
U
V
W
X
Y
Z
其他