下面通过代码给大家介绍java多线程通讯之wait notify的区别,具体内容如下所示:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
|
class res{
public string username;
public string sex;
}
class out extends thread{
res res;
public out(res res){
this .res=res;
}
@override
public void run() {
//写操作
int count= 0 ;
while ( true ){
// synchronized (res.getclass()){
if (count== 0 ){ //偶数
res.username= "小明" ;
res.sex= "男" ;
} else { //奇数
res.username= "小红" ;
res.sex= "女" ;
}
count=(count+ 1 )% 2 ;
// }
}
}
}
class input extends thread{
res res;
public input(res res){
this .res=res;
}
@override
public void run() {
while ( true ){
// synchronized (res.getclass()){
system.out.println(res.username+ "," +res.sex);
// }
}
}
}
public class outinputthread {
public static void main(string[] args) {
res res = new res();
out out = new out(res);
input input = new input(res);
out.start();
input.start();
}
}
小红,女
小红,女
小红,女
小红,女
小红,女
小红,女
小红,女
小红,女
小红,女
|
出现以上结果??消费者一直消费或者生产者一直生产
解决方法:生产者生产完成后消费者方可消费,否者不可消费,消费者未消费或者未消费完生产者不可生产,一次生产一次消费。其实也就是保证对res共享资源的操作同一时刻仅有同一个线程进行操作,
wait、notify、notifyall方法
wait、notify、notifyall是三个定义在object类里的方法,可以用来控制线程的状态。
这三个方法最终调用的都是jvm级的native方法。随着jvm运行平台的不同可能有些许差异。
如果对象调用了wait方法就会使持有该对象的线程把该对象的控制权交出去,然后处于等待状态。当前线程从运行变为阻塞,释放所的资源
如果对象调用了notify方法就会通知某个正在等待这个对象的控制权的线程可以继续运行。让持有该锁的线程从阻塞态变为就绪。
如果对象调用了notifyall方法就会通知所有等待这个对象控制权的线程继续运行。
注意:一定要在线程同步中使用,并且是同一个锁的资源
通过以下方式即可完成需求。
生产者获取res.getclass锁后,如果flag为true生产者通过调用res.getclass.wait进行等待,此时其他线程可获取该锁,如果flag为false,进行生产,然后设置flag为true保证资源消费后方可再生产,接着通过notify通知其他唤醒其他线程。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
|
class res{
public string username;
public string sex;
//true 生产者等待,消费者可消费 false生产者可以生产,消费者不可消费
public boolean flag= false ;
}
class out extends thread{
res res;
public out(res res){
this .res=res;
}
@override
public void run() {
//写操作
int count= 0 ;
while ( true ){
synchronized (res.getclass()){
if (res.flag){
try {
res.getclass().wait(); //让当前线程从运行变为阻塞,并且释放所的资源
} catch (interruptedexception e) {
e.printstacktrace();
}
}
if (count== 0 ){ //偶数
res.username= "小明" ;
res.sex= "男" ;
} else { //奇数
res.username= "小红" ;
res.sex= "女" ;
}
count=(count+ 1 )% 2 ;
res.flag= true ;
res.getclass().notify();
}
}
}
}
class input extends thread{
res res;
public input(res res){
this .res=res;
}
@override
public void run() {
while ( true ){
synchronized (res.getclass()){
if (!res.flag){
try {
res.getclass().wait();
} catch (interruptedexception e) {
e.printstacktrace();
}
}
system.out.println(res.username+ "," +res.sex);
res.flag= false ;
res.getclass().notify();
}
}
}
}
public class outinputthread {
public static void main(string[] args) {
res res = new res();
out out = new out(res);
input input = new input(res);
out.start();
input.start();
}
}
|
输出如下:
小明,男
小红,女
小明,男
小红,女
小明,男
小红,女
小明,男
小红,女
如果去掉notify会怎样?去掉一个?去掉两个?
去掉一个生产者可以打印多个(但是也不多),去掉消费者仅可打印一个,去掉两个可能不打印,也可能打印1个,所以wait、notify必须成对使用
wait(用于同步中)与sleep区别?
都是做休眠,wait需要notify
对于sleep方法,我们首先要知道该方法是属于thread类中的。而wait方法,则是属于object类中的。
sleep方法导致了程序暂停执行指定的时间,让出cpu该其他线程,但是他的监控状态依然保持者,当指定的时间到了又会自动恢复运行状态。
在调用sleep方法的过程中,线程不会释放对象锁。
而当调用wait方法的时候,线程会放弃对象锁,进入等待此对象的等待锁定池,只有针对此对象调用notify方法后本线程才进入对象锁定池准备获取对象锁进入运行状态。
总结
以上所述是小编给大家介绍的java多线程通讯之wait,notify的区别详解,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对服务器之家网站的支持!
原文链接:https://www.cnblogs.com/losemyfuture/archive/2018/07/24/9357846.html