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 多线程:线程安全与同步控制的深度解析
本文介绍了 Java 多线程开发的关键技术,涵盖线程的创建与启动、线程安全问题及其解决方案,包括 synchronized 关键字、原子类和线程间通信机制。通过示例代码讲解了多线程编程中的常见问题与优化方法,帮助开发者提升程序性能与稳定性。
494 0
|
Java 数据挖掘 调度
Java 多线程创建零基础入门新手指南:从零开始全面学习多线程创建方法
本文从零基础角度出发,深入浅出地讲解Java多线程的创建方式。内容涵盖继承`Thread`类、实现`Runnable`接口、使用`Callable`和`Future`接口以及线程池的创建与管理等核心知识点。通过代码示例与应用场景分析,帮助读者理解每种方式的特点及适用场景,理论结合实践,轻松掌握Java多线程编程 essentials。
867 5
|
监控 搜索推荐 Java
Java 多线程最新实操技术与应用场景全解析:从基础到进阶
本文深入探讨了Java多线程的现代并发编程技术,涵盖Java 8+新特性,如CompletableFuture异步处理、Stream并行流操作,以及Reactive编程中的Reactor框架。通过具体代码示例,讲解了异步任务组合、并行流优化及响应式编程的核心概念(Flux与Mono)。同时对比了同步、CompletableFuture和Reactor三种实现方式的性能,并总结了最佳实践,帮助开发者构建高效、扩展性强的应用。资源地址:[点击下载](https://pan.quark.cn/s/14fcf913bae6)。
670 3
|
算法 Java 调度
Java多线程基础
本文主要讲解多线程相关知识,分为两部分。第一部分涵盖多线程概念(并发与并行、进程与线程)、Java程序运行原理(JVM启动多线程特性)、实现多线程的两种方式(继承Thread类与实现Runnable接口)及其区别。第二部分涉及线程同步(同步锁的应用场景与代码示例)及线程间通信(wait()与notify()方法的使用)。通过多个Demo代码实例,深入浅出地解析多线程的核心知识点,帮助读者掌握其实现与应用技巧。
238 1
java 多线程异常处理
本文介绍了Java中ThreadGroup的异常处理机制,重点讲解UncaughtExceptionHandler的使用。通过示例代码展示了当线程的run()方法抛出未捕获异常时,JVM如何依次查找并调用线程的异常处理器、线程组的uncaughtException方法或默认异常处理器。文章还提供了具体代码和输出结果,帮助理解不同处理器的优先级与执行逻辑。
286 1
|
数据采集 存储 网络协议
Java HttpClient 多线程爬虫优化方案
Java HttpClient 多线程爬虫优化方案
|
Java 数据库
【Java多线程】对线程池的理解并模拟实现线程池
【Java多线程】对线程池的理解并模拟实现线程池
453 155
|
存储 监控 Java
Java多线程优化:提高线程池性能的技巧与实践
Java多线程优化:提高线程池性能的技巧与实践
754 1
|
设计模式 监控 Java
Java多线程基础-11:工厂模式及代码案例之线程池(一)
本文介绍了Java并发框架中的线程池工具,特别是`java.util.concurrent`包中的`Executors`和`ThreadPoolExecutor`类。线程池通过预先创建并管理一组线程,可以提高多线程任务的效率和响应速度,减少线程创建和销毁的开销。
1326 2
|
安全 算法 Java
17 Java多线程(线程创建+线程状态+线程安全+死锁+线程池+Lock接口+线程安全集合)(下)
17 Java多线程(线程创建+线程状态+线程安全+死锁+线程池+Lock接口+线程安全集合)
322 6