一道多线程通信实例分析

简介:

程序如下:

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
public  static  void  main(String[] args)  throws   Exception{
 
     final  List list =  new  ArrayList();
 
     final  Object lock =  new  Object();
 
     Thread t1 =  new  Thread( new  Runnable() {
         @Override
         public  void  run() {
 
             synchronized  (lock){
 
                 for ( int  i =  0  ; i <  10  ; i++){
 
                     list.add(i);
                     if (list.size() ==  5 ){
                         lock.notify();
                         System.out.println(Thread.currentThread().getName() +  "发出通知!" );
                     }
                 }
 
             }
             System.out.println(Thread.currentThread().getName() +  "execute over!" );
 
         }
     });
 
     Thread t2 =  new  Thread( new  Runnable() {
         @Override
         public  void  run() {
 
             synchronized  (lock){
 
                 if (list.size() !=  5 ){
                     try  {
                         lock.wait();
                     catch  (InterruptedException e) {
                         e.printStackTrace();
                     }
                 }
                 System.out.println(Thread.currentThread().getName() +  " 收到通知!" );
             }
 
             System.out.println(Thread.currentThread().getName() +  "execute over!" );
 
         }
     });
 
     t2.start();
 
     Thread.sleep( 1000 );
 
     t1.start();
}


分析:

程序的意图本是利用多线程之间的通信,利用wait/notify实现,可是运行的结果是虽然线程T1发出了通知,但是线程T2并没有立即收到通知进行执行,这是为什么呢? 因为只有线程T1执行完毕释放了锁,T2才能执行,那么也就是说wait/notify并不是实时的(wait释放了锁,而notify没有释放锁导致的),那么线程之间实时的通信该怎么做呢?可以利用CountDownLatch来实现。


对程序的改进:

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
public  static  void  main(String[] args)  throws   Exception{
 
     final  List list =  new  ArrayList();
 
     final  Object lock =  new  Object();
 
     final  CountDownLatch countDownLatch =  new  CountDownLatch( 1 );
 
     Thread t1 =  new  Thread( new  Runnable() {
         @Override
         public  void  run() {
 
                 for ( int  i =  0  ; i <  10  ; i++){
 
                     list.add(i);
                     if (list.size() ==  5 ){
                         countDownLatch.countDown();
                         System.out.println(Thread.currentThread().getName() +  "发出通知!" );
                     }
                 }
 
             System.out.println(Thread.currentThread().getName() +  "execute over!" );
 
         }
     });
 
     Thread t2 =  new  Thread( new  Runnable() {
         @Override
         public  void  run() {
 
                 if (list.size() !=  5 ){
                     try  {
                         countDownLatch.await();
                     catch  (InterruptedException e) {
                         e.printStackTrace();
                     }
                 System.out.println(Thread.currentThread().getName() +  " 收到通知!" );
             }
 
             System.out.println(Thread.currentThread().getName() +  "execute over!" );
 
         }
     });
 
     t2.start();
 
     Thread.sleep( 1000 );
 
     t1.start();
}


本文转自zfz_linux_boy 51CTO博客,原文链接:http://blog.51cto.com/zhangfengzhe/1875221,如需转载请自行联系原作者

相关文章
|
4月前
|
设计模式 消息中间件 安全
【JUC】(3)常见的设计模式概念分析与多把锁使用场景!!理解线程状态转换条件!带你深入JUC!!文章全程笔记干货!!
JUC专栏第三篇,带你继续深入JUC! 本篇文章涵盖内容:保护性暂停、生产者与消费者、Park&unPark、线程转换条件、多把锁情况分析、可重入锁、顺序控制 笔记共享!!文章全程干货!
390 2
|
5月前
|
数据采集 存储 弹性计算
高并发Java爬虫的瓶颈分析与动态线程优化方案
高并发Java爬虫的瓶颈分析与动态线程优化方案
|
并行计算 安全 Java
Python GIL(全局解释器锁)机制对多线程性能影响的深度分析
在Python开发中,GIL(全局解释器锁)一直备受关注。本文基于CPython解释器,探讨GIL的技术本质及其对程序性能的影响。GIL确保同一时刻只有一个线程执行代码,以保护内存管理的安全性,但也限制了多线程并行计算的效率。文章分析了GIL的必要性、局限性,并介绍了多进程、异步编程等替代方案。尽管Python 3.13计划移除GIL,但该特性至少要到2028年才会默认禁用,因此理解GIL仍至关重要。
1101 16
Python GIL(全局解释器锁)机制对多线程性能影响的深度分析
|
调度 开发者
核心概念解析:进程与线程的对比分析
在操作系统和计算机编程领域,进程和线程是两个基本而核心的概念。它们是程序执行和资源管理的基础,但它们之间存在显著的差异。本文将深入探讨进程与线程的区别,并分析它们在现代软件开发中的应用和重要性。
522 4
|
Java
JAVA多线程通信:为何wait()与notify()如此重要?
在Java多线程编程中,`wait()` 和 `notify()/notifyAll()` 方法是实现线程间通信的核心机制。它们通过基于锁的方式,使线程在条件不满足时进入休眠状态,并在条件满足时被唤醒,从而确保数据一致性和同步。相比其他通信方式,如忙等待,这些方法更高效灵活。 示例代码展示了如何在生产者-消费者模型中使用这些方法实现线程间的协调和同步。
170 3
|
安全 Java
Java多线程通信新解:本文通过生产者-消费者模型案例,深入解析wait()、notify()、notifyAll()方法的实用技巧
【10月更文挑战第20天】Java多线程通信新解:本文通过生产者-消费者模型案例,深入解析wait()、notify()、notifyAll()方法的实用技巧,包括避免在循环外调用wait()、优先使用notifyAll()、确保线程安全及处理InterruptedException等,帮助读者更好地掌握这些方法的应用。
231 1
|
安全 Java 开发者
Java多线程中的`wait()`、`notify()`和`notifyAll()`方法,探讨了它们在实现线程间通信和同步中的关键作用
本文深入解析了Java多线程中的`wait()`、`notify()`和`notifyAll()`方法,探讨了它们在实现线程间通信和同步中的关键作用。通过示例代码展示了如何正确使用这些方法,并分享了最佳实践,帮助开发者避免常见陷阱,提高多线程程序的稳定性和效率。
350 1
|
Java
在Java多线程编程中,`wait()` 和 `notify()/notifyAll()` 方法是线程间通信的核心机制。
在Java多线程编程中,`wait()` 和 `notify()/notifyAll()` 方法是线程间通信的核心机制。它们通过基于锁的方式,使线程在条件不满足时进入休眠状态,并在条件成立时被唤醒,从而有效解决数据一致性和同步问题。本文通过对比其他通信机制,展示了 `wait()` 和 `notify()` 的优势,并通过生产者-消费者模型的示例代码,详细说明了其使用方法和重要性。
205 1
|
4月前
|
Java
如何在Java中进行多线程编程
Java多线程编程常用方式包括:继承Thread类、实现Runnable接口、Callable接口(可返回结果)及使用线程池。推荐线程池以提升性能,避免频繁创建线程。结合同步与通信机制,可有效管理并发任务。
229 6
|
7月前
|
Java API 微服务
为什么虚拟线程将改变Java并发编程?
为什么虚拟线程将改变Java并发编程?
386 83

热门文章

最新文章