java多线程的等待唤醒机制及如何解决同步过程中的安全问题

简介:
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
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
/*
class Person{
    String name;
    String sex;
    boolean flag = true;
    public void setPerson(String name, String sex){ 
                  this.sex=sex;
                  this.name=name;  
    }
}
class Input implements Runnable{
    int x=0;
    Person p;
    Input(Person p){
       this.p=p;
    }
    public void run(){
        while(true){
            if(x==1){
               p.setPerson("hjz", "man");
            }
            else p.setPerson("哈哈哈", "女女女女");
            x=(x+1)%2;
        }
    }
}
 
class Output implements Runnable{
    int x=0;
    Person p;
    Output(Person p){
       this.p=p;
    }
    public void run(){
        while(true){
            System.out.println(p.name + "....." + p.sex);
        }
    }
}
public class Test{
     public static void main(String[] args){
          Person p = new Person();
          new Thread(new Input(p)).start();
          new Thread(new Output(p)).start();
     }
}
*/
 
/*
输出的结果:
哈哈哈.....man
hjz.....man
hjz.....man
哈哈哈.....man
hjz.....女女女女
*/
 
//线程安全隐患出现:首先考虑到是多线程操作了同一资源,所以要用同步!
/*
class Person{
    String name;
    String sex;
    boolean flag = true;
    public void setPerson(String name, String sex){ 
                  this.sex=sex;
                  this.name=name;  
    }
}
 
class Input implements Runnable{
    int x=0;
    Person p;
    Input(Person p){
       this.p=p;
    }
    public void run(){
        while(true){
           synchronized(new Object()){
                if(x==1){
                   p.setPerson("hjz", "man");
                }
                else p.setPerson("哈哈哈", "女女女女");
                x=(x+1)%2;
           }
        }
    }
}
 
class Output implements Runnable{
    int x=0;
    Person p;
    Output(Person p){
       this.p=p;
    }
    public void run(){
        while(true){
            System.out.println(p.name + "....." + p.sex);
        }
    }
}
public class Test{
     public static void main(String[] args){
          Person p = new Person();
          new Thread(new Input(p)).start();
          new Thread(new Output(p)).start();
     }
}
  */
 
//同步完成之后,发现还是出现安全隐患的情况,在考虑一下是否访问统一资源的多个线程用的是同一个锁!
//本例中的应将输入输出一起同步(注意输入输出不在同一个线程之中,输出线程不会获得 Person p对象的控制权!)
/*   class Input implements Runnable{
    int x=0;
    Person p;
    
    Input(Person p){
       this.p=p;
    }
    public void run(){
        while(true){
           synchronized(p){
                if(p.flag){
                  try{
                      p.wait();
                    }catch(InterruptedException e){
                    }
                }
                if(!p.flag){
                    if(x==1){
                       p.setPerson("hjz", "man");
                    }
                    else p.setPerson("哈哈哈", "女女女女");
                    x=(x+1)%2;
                }
                
                p.flag=true;
                p.notify();
                
           }
        }
    }
} */
 
 
//现在的代码是将同步放到函数里!真正开发过的时候就是这样实现,也就是我们多个线程同事操作一个类对象
//调用该类提供的对外方法,并将调用的方法进行同步!防止安全隐患!
class  Person{
    String name;
    String sex;
    boolean  flag =  true ;
    public  void  setPerson(String name, String sex){
        synchronized ( this ){
          if (!flag){
              try {
                 wait();
              } catch (InterruptedException e){}
          }
          if (flag){
                  this .sex=sex;
                  try {
                     Thread.sleep( 100 );
                  } catch (InterruptedException e){}
                  this .name=name;
          }
          flag= false ;
          notify();
        }
    }
    
    public  void  outPerson(){
       synchronized ( this ){
           if (flag){
              try {
                  wait();
              } catch (InterruptedException e){}
           }
           if (!flag){
               System.out.println(name +  "....."  + sex);
           }
           flag= true ;
           notify();
       }
    }
}
 
class  Input  implements  Runnable{
    int  x= 0 ;
    Person p;
    
    Input(Person p){
       this .p=p;
    }
    public  void  run(){
        while ( true ){
                    if (x== 1 ){
                       p.setPerson( "hjz" "man" );
                    }
                    else  p.setPerson( "哈哈哈" "女女女女" );
                    x=(x+ 1 )% 2 ;
        }
    }
}
 
class  Output  implements  Runnable{
    int  x= 0 ;
    Person p;
    Output(Person p){
       this .p=p;
    }
    public  void  run(){
        while ( true ){
            p.outPerson();
        }
    }
 
 
public  class  Test{
     public  static  void  main(String[] args){
          Person p =  new  Person();
          new  Thread( new  Input(p)).start();
          new  Thread( new  Output(p)).start();
     }
}

  










本文转自 小眼儿 博客园博客,原文链接:http://www.cnblogs.com/hujunzheng/p/3889183.html,如需转载请自行联系原作者
目录
相关文章
|
Java
java多线程的等待唤醒机制及如何解决同步过程中的安全问题
/* class Person{ String name; String sex; boolean flag = true; public void setPerson(String name, String sex){ this.
610 0
|
8月前
|
监控 Java API
|
8月前
|
Java 容器
Java——使用多线程模拟真实高并发业务并保证安全性(二)
Java——使用多线程模拟真实高并发业务并保证安全性(二)
|
8月前
|
Java 容器
Java——使用多线程模拟真实高并发业务并保证安全性(一)
Java——使用多线程模拟真实高并发业务并保证安全性(一)
|
8月前
|
Java 程序员 开发者
疫情过后,Java开发者如何应对多线程与高并发面试题目?
发某粉丝年前参加某个NB企业的面试题列表: 聊聊synchronized的CPU原语级别实现 有一千万个数,写一个程序进行高效求和 已知2开平方为1.414,如何不用数学库,求开平方的值,精确到小数点儿后面10位 编码实现两个线程,线程A不断打印1-10的数字,要求在打印到第五个数字的时候通知线程B 自定义线程池需要指定哪7个参数,为什么不建议使用JUC内置线程池? 高并发、任务执行时间短的业务怎样使用线程池? 并发不高、任务执行时间长的业务怎样使用线程池? 并发高、业务执行时间长的业务怎样使用线程池? 设计一个12306网站,能够撑住最高百万级别TPS(淘宝最高54万TPS),你该如何实现
|
8月前
|
Java
【Java|多线程与高并发】死锁以及哲学家吃饭问题
死锁(Deadlock)是多线程编程中的一个常见问题,指的是两个或多个线程相互等待对方释放资源,导致程序无法继续执行的状态。
|
8月前
|
安全 Java 开发者
【Java|多线程与高并发】JUC中常用的类和接口
JUC是Java并发编程中的一个重要模块,全称为Java Util Concurrent(Java并发工具包),它提供了一组用于多线程编程的工具类和框架,帮助开发者更方便地编写线程安全的并发代码。
|
8月前
|
安全 Java
【Java|多线程与高并发】CAS以及ABA问题
CAS(Compare and Swap,“比较和交换”)是一种并发编程中常用的原子操作,用于解决多线程环境下的数据竞争和并发访问问题。
|
8月前
|
设计模式 缓存 Java
【Java|多线程与高并发】线程池详解
Java线程池是一种用于管理和重用线程的机制,它可以在需要执行任务时,从线程池中获取线程,执行任务,然后将线程放回池中,以便后续使用。线程池可以有效地管理线程的数量,提高程序的性能和资源利用率。
【Java|多线程与高并发】线程池详解
|
8月前
|
安全 Java
【Java|多线程与高并发】定时器(Timer)详解
在Java中,定时器Timer类是用于执行定时任务的工具类。它允许你安排一个任务在未来的某个时间点执行,或者以固定的时间间隔重复执行。