一个简答的生产者-消费者多线程模型
来源:互联网 发布:出售备案域名 编辑:程序博客网 时间:2024/04/29 21:53
生产者消费者模型
同一段代码,分别设置produce和consumer的频率(通过sleep的长短控制)。
第一种情况produce后,sleep(
500
),consumer后,sleep(
100
),也就是取消息快,生产消息慢。这种情况正常。代码如下
package
test;
import
java.util.Vector;
public
class
Producer
extends
Thread
{
static
final
int
MAXQUEUE =
5
;
private
Vector messages =
new
Vector();
@Override
public
void
run()
{
try
{
while
(
true
)
{
putMessage();
//
sleep(
500
);
}
}
catch
(InterruptedException e)
{
}
}
public
synchronized
void
putMessage()
throws
InterruptedException
{
while
(messages.size()== MAXQUEUE)
{
System.out.println(
"messages full,wait......"
);
wait();
}
String element =
new
java.util.Date().toString();
messages.addElement(element);
System.out.println(
"put message: "
+element+
";size:"
+messages.size());
notify();
//Later, when the necessary event happens, the thread that is running it calls notify() from a block synchronized on the same object.
}
// Called by Consumer
public
synchronized
String getMessage()
throws
InterruptedException
{
String message =
null
;
while
(messages.size()==
0
)
{
System.out.println(
"messages empty,wait......"
);
wait();
}
//By executing wait() from a synchronized block, a thread gives up its hold on the lock and goes to sleep.}
message =(String) messages.firstElement();
messages.removeElement(message);
System.out.println(
"get message: "
+message+
";size:"
+messages.size());
return
message;
}
public
static
void
main(String args[])
{
Producer producer =
new
Producer();
producer.start();
new
Consumer (producer).start();
}
}
class
Consumer
extends
Thread
{
Producer producer;
Consumer (Producer p)
{
producer = p;
}
@Override
public
void
run()
{
try
{
while
(
true
)
{
String message = producer.getMessage();
//System.out.println("get message: "+ message);
sleep(
100
);
}
}
catch
(InterruptedException e)
{
e.printStackTrace();
}
}
}
运行结果:
put message: Wed Feb
17
14
:
24
:
19
CST
2016
;size:
1
get message: Wed Feb
17
14
:
24
:
19
CST
2016
;size:
0
messages empty,wait......
put message: Wed Feb
17
14
:
24
:
19
CST
2016
;size:
1
get message: Wed Feb
17
14
:
24
:
19
CST
2016
;size:
0
messages empty,wait......
put message: Wed Feb
17
14
:
24
:
20
CST
2016
;size:
1
get message: Wed Feb
17
14
:
24
:
20
CST
2016
;size:
0
messages empty,wait......
put message: Wed Feb
17
14
:
24
:
20
CST
2016
;size:
1
get message: Wed Feb
17
14
:
24
:
20
CST
2016
;size:
0
messages empty,wait......
put message: Wed Feb
17
14
:
24
:
21
CST
2016
;size:
1
get message: Wed Feb
17
14
:
24
:
21
CST
2016
;size:
0
messages empty,wait......
put message: Wed Feb
17
14
:
24
:
21
CST
2016
;size:
1
get message: Wed Feb
17
14
:
24
:
21
CST
2016
;size:
0
messages empty,wait......
put message: Wed Feb
17
14
:
24
:
22
CST
2016
;size:
1
get message: Wed Feb
17
14
:
24
:
22
CST
2016
;size:
0
messages empty,wait......
put message: Wed Feb
17
14
:
24
:
22
CST
2016
;size:
1
get message: Wed Feb
17
14
:
24
:
22
CST
2016
;size:
0
messages empty,wait......
put message: Wed Feb
17
14
:
24
:
23
CST
2016
;size:
1
get message: Wed Feb
17
14
:
24
:
23
CST
2016
;size:
0
messages empty,wait......
put message: Wed Feb
17
14
:
24
:
23
CST
2016
;size:
1
get message: Wed Feb
17
14
:
24
:
23
CST
2016
;size:
0
messages empty,wait......
put message: Wed Feb
17
14
:
24
:
24
CST
2016
;size:
1
get message: Wed Feb
17
14
:
24
:
24
CST
2016
;size:
0
messages empty,wait......
put message: Wed Feb
17
14
:
24
:
24
CST
2016
;size:
1
get message: Wed Feb
17
14
:
24
:
24
CST
2016
;size:
0
messages empty,wait......
2、第二种情况,把两个sleep的时间调换下,也就是produce后,sleep(100),consumer后,sleep(500),也就是取消息慢,生产消息快。这种情况就出现了问题,如果队列满了,produce线程等待,consumer线程取完消息就hang住了,线程全部挂住了。运行结果如下:
put message: Wed Feb 17 14:27:00 CST 2016;size:1
get message: Wed Feb 17 14:27:00 CST 2016;size:0
put message: Wed Feb 17 14:27:00 CST 2016;size:1
put message: Wed Feb 17 14:27:00 CST 2016;size:2
put message: Wed Feb 17 14:27:00 CST 2016;size:3
put message: Wed Feb 17 14:27:00 CST 2016;size:4
get message: Wed Feb 17 14:27:00 CST 2016;size:3
put message: Wed Feb 17 14:27:01 CST 2016;size:4
put message: Wed Feb 17 14:27:01 CST 2016;size:5
messages full,wait......
get message: Wed Feb 17 14:27:00 CST 2016;size:4
get message: Wed Feb 17 14:27:00 CST 2016;size:3
get message: Wed Feb 17 14:27:00 CST 2016;size:2
get message: Wed Feb 17 14:27:01 CST 2016;size:1
get message: Wed Feb 17 14:27:01 CST 2016;size:0
messages empty,wait......
运行到这里就结束了,后面没有输出了
分析后,感觉应该和wait、notify有关系。
第二种情况下,生产消息快,队列慢了后就wait(),consumer线程取消息,直到队列空了之后,consumer线程只有一个wait(),并没有类似于notify的机制去通知produce线程,导致一直挂起;
而第一种情况下,取消息快,放消息慢,不存在队列满,队列只会空。队列空了后,consumer线程就wait(),等produce线程放入消息后,就会notify
还没想到解决办法,有哪个大神看出问题来就给个解答吧。
问题解决了,getMessage()函数改为如下:
public
synchronized
String getMessage()
throws
InterruptedException
{
String message =
null
;
while
(messages.size()==
0
)
{
System.out.println(
"messages empty,wait......"
);
notify();
return
null
;
}
//By executing wait() from a synchronized block, a thread gives up its hold on the lock and goes to sleep.}
message =(String) messages.firstElement();
messages.removeElement(message);
System.out.println(
"get message: "
+message+
";size:"
+messages.size());
return
message;
}
- 一个简答的生产者-消费者多线程模型
- 一个生产者与消费者模型的多线程例子程序
- 多线程---生产者-消费者模型
- [多线程] 生产者消费者模型的BOOST实现
- 简单的win32多线程---生产者、消费者模型
- Linux 下多线程的消费者-生产者模型
- 多线程模型:生产者和消费者
- 多线程之生产者消费者模型
- java多线程生产者、消费者模型
- 多线程之生产者消费者模型
- Java多线程 -- 生产者消费者模型
- 多线程之生产者消费者模型
- Java 多线程:生产者消费者模型
- Python 多线程 生产者消费者模型
- Java 多线程:生产者消费者模型
- linux多线程生产者消费者模型
- 多线程之生产者消费者模型
- Java 多线程学习之生产者消费者模型:一个较完善的实现
- 101. Symmetric Tree
- Appium跑python脚本自动生成简单测试结果报告
- BZOJ 3289 Mato的文件管理 莫队算法
- Linux安装Mongodb
- CF 650A Watchmen
- 一个简答的生产者-消费者多线程模型
- Android学习第六课 计时器小应用
- hdoj--1716--排列2(暴力水题)
- 最小乘积
- 【iOS界面开发】视图开发技巧
- 使用CSS3线性渐变(linear-gradient)实现文本波浪线效果
- js基础与DOM
- MySQL数据库总结(7)视图
- 蓝桥杯历届-三羊献瑞