一道多线程通信实例分析

程序如下:

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来实现。

对程序的改进:

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();
}
时间: 2024-10-04 19:34:41

一道多线程通信实例分析的相关文章

java中多线程通信实例:生产者消费者模式

线程间的通信: 其实就是多个线程再操作同一个资源,但是操作的动作不同   当某个线程进入synchronized块后,共享数据的状态不一定满足该线程的需要,需要其他线程改变共享数据的状态后才能运行,而由于当时线程对共享资源时独占的,它必须解除对共享资源的锁定的状态,通知其他线程可以使用该共享资源. Java中的 wait(),notify(),notifyAll()可以实现线程间的通信. 生产者--消费者问题是典型的线程同步和通信问题 /** * 生产者和消费者问题,生产者生成出产品,消费者去购

python多线程同步实例分析

进程之间通信与线程同步是一个历久弥新的话题,对编程稍有了解应该都知道,但是细说又说不清.一方面除了工作中可能用的比较少,另一方面就是这些概念牵涉到的东西比较多,而且相对较深.网络编程,服务端编程,并发应用等都会涉及到.其开发和调试过程都不直观.由于同步通信机制的原理都是想通的,本文希通过望借助python实例来将抽象概念具体化. 阅读之前可以参考之前的一篇文章:python多线程与多进程及其区别,了解一下线程和进程的创建. python多线程同步 python中提供两个标准库thread和thr

java多线程三之线程协作与通信实例

多线程的难点主要就是多线程通信协作这一块了,前面笔记二中提到了常见的同步方法,这里主要是进行实例学习了,今天总结了一下3个实例: 1.银行存款与提款多线程实现,使用Lock锁和条件Condition.     附加 : 用监视器进行线程间通信 2.生产者消费者实现,使用LinkedList自写缓冲区. 3.多线程之阻塞队列学习,用阻塞队列快速实现生产者消费者模型.    附加:用布尔变量关闭线程        在三种线程同步方法中,我们这里的实例用Lock锁来实现变量同步,因为它比较灵活直观.

多线程之间的通信实例讲解

                 多线程之间的通信实例讲解对于线程来说,说白了,就是一个函数,如果大家对于这章函数都有理解,那我对于操作系统,线程和进程间的通信会有一个新的认识!接下来我会对每一行代码进行注释,在此过程中,大家也可以对c语言有一个崭新的认识. 第一个函数,创建两个线程. #include <stdio.h>#include <pthread.h>    这个头函数要包含,因为我们后续用的函数都是系统调用,因此需要申请头函数   这样在编译的时候,就可以找到此函数的源

Chromium多线程通信的Closure机制分析

为了充分利用CPU多核特性,Chromium在启动时会创建很多线程,来负责执行不同的操作.这样就涉及到了多线程通信问题.Chromium为每一个线程都创建了一个消息队列.当一个线程需要另一个线程执行某一操作时,就向该线程的消息队列发送一个Closure.这个Closure最终在目标线程中得到执行.这种基于Closure的多线程通信方式在Chromium中使用得很普通,因此本文就对它的实现进行分析. 老罗的新浪微博:http://weibo.com/shengyangluo,欢迎关注! Closu

vc 基于对话框多线程编程实例——线程之间的通信

 vc基于对话框多线程编程实例--线程之间的通信 实例: vc 基于对话框多线程编程实例--线程之间的通信,码迷,mamicode.com

java基础知识回顾之java Thread类学习(八)--java多线程通信等待唤醒机制经典应用(生产者消费者)

 *java多线程--等待唤醒机制:经典的体现"生产者和消费者模型 *对于此模型,应该明确以下几点: *1.生产者仅仅在仓库未满的时候生产,仓库满了则停止生产. *2.消费者仅仅在有产品的时候才能消费,仓空则等待. *3.当消费者发现仓储没有产品可消费的时候,会唤醒等待生产者生产. *4.生产者在生产出可以消费的产品的时候,应该通知等待的消费者去消费. 下面先介绍个简单的生产者消费者例子:本例只适用于两个线程,一个线程生产,一个线程负责消费. 生产一个资源,就得消费一个资源. 代码如下: pub

HTTP的上传文件实例分析

HTTP的上传文件实例分析 由于论坛不支持Word写文章发帖. 首先就是附件发送怎么搞,这个必须解决.论坛是php的.我用Chrome类浏览器跟踪请求,但是上传的文件流怎么发过去没找到,估计流可能多或者什么的不好显示,只知道发送了文件名字.需要实际了解下post文件,不能只会后台或界面不了解前台数据处理和协议怎么传送数据. 图中:有些相关文章 HTTP请求中的form data和request payload的区别 AJAX POST请求中参数以form data和request payload

深入浅出Alljoyn——实例分析之远程调用(Method)篇

深入浅出就是很深入的学习了很久,还是只学了毛皮,呵呵! 服务端完整代码: 1 #include <qcc/platform.h> 2 3 #include <assert.h> 4 #include <signal.h> 5 #include <stdio.h> 6 #include <vector> 7 8 #include <qcc/String.h> 9 10 #include <alljoyn/BusAttachment