`
javandroid
  • 浏览: 25593 次
  • 性别: Icon_minigender_1
文章分类
社区版块
存档分类
最新评论

多线程之三 线程通信

 
阅读更多

1.传统的线程通信:wait和notify/notifyall

可以借助于Object类提供的wait()、notify()、notifyAll()三个方法,这三个方法属于Object类。但这三个方法必须由同步监视器对象来调用,这可分为两种情况
①对于用synchronized修饰的同步方法,因为该类的默认实例(this)就是同步监视器,所以可以在同步方法中直接调用这三个方法。
②对于用synchronized修饰的同步代码块,同步监视器是synchronized后括号里的对象,所以必须使用该对象调用这三个方法。

注意:notify()方法只能随机唤醒一个线程。如果要唤醒所有线程,请使用notifyAll()。


以下面demo为例,来说明其用法。

public class WaitAndNotifyDemo {
    // 锁
    static Object lock = new Object();
    
    private static class T1 implements Runnable {
        
        @Override
        public void run() {
            synchronized (lock) {
                System.out.println("T1开始");
                
                try {
                    System.out.println("T1开始等待");
                    lock.wait(5000);//wait,释放锁
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }   
                
                System.out.println("T1结束");               
            }
        }
    }

    static private class T2 implements Runnable {

        @Override
        public void run() {           
            synchronized (lock) {
                System.out.println("T2开始通知");
                lock.notify();//通知
                
                try {
                    Thread.sleep(5000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                
                System.out.println("T2结束");
            }           
        }
    }

    public static void main(String[] args) {
        Thread th1 = new Thread(new T1());
        Thread th2 = new Thread(new T2());
        th1.start();
        th2.start();
    }
}


2.使用Condition控制线程通信

如果程序不用synchronized关键字来进行同步,而是用Lock对象来保证同步,则系统中不存在隐式的同步监视器,也就不能使用wait()、notify()、notifyAll()方法进行线程通信了。
使用Lock对象的方式,Java提供了一个Condition类来保持协调,使用Condition可以让那些已经得到Lock对象却无法继续执行的线程释放Lock对象,Condition对象也可以唤醒其他处于等待的线程。
Condition将同步监视器方法wait()、notify()、notifyAll()分解成截然不同的对象,以便通过将这些对象与Lock对象组合使用,为每个对象提供多个等待集(wait-set)。在这种情况下,Lock替代了同步方法和同步代码块,Condition替代了同步监视器的功能。
Condition实例被绑定在一个Lock对象上。要获得特定Lock实例的Condition实例,调用Lock对象的newCondition()方法获得即可。Condition类提供了以下三个方法:
await():
signal():

signalAll():


下面则将上面的demo改为重入锁实现,并使用Condition来控制线程通信

public class ConditionDemo {
    // 锁
    private static ReentrantLock lock = new ReentrantLock();   
    private static Condition condition = lock.newCondition();

    private static class T3 implements Runnable {

        @Override
        public void run() {
            // 加锁
            lock.lock();
            System.out.println("T3开始");
            try {
                System.out.println("T3开始等待");
                condition.await(5, TimeUnit.SECONDS);// 等待5秒
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            System.out.println("T3结束");
            // 释放锁
            lock.unlock();
        }
    }

    private static class T4 implements Runnable {

        @Override
        public void run() {
            //加锁
            lock.lock();
            System.out.println("T4开始");

            System.out.println("T4开始等待");
            condition.signal();//通知

            System.out.println("T4结束");
            //释放锁
            lock.unlock();
        }
    }
    
    public static void main(String[] args) {
        Thread th3 = new Thread(new T3());
        Thread th4 = new Thread(new T4());
        th3.start();
        th4.start();
    }
}

3.使用阻塞队列(BlockingQueue)控制线程通信

Java5提供了一个BlockingQueue接口,虽然BlockingQueue也是Queue的子接口,但它的主要用途不是作为容器,而是作为线程同步的工具。
BlockingQueue具有一个特征:当生产者线程试图向BlockingQueue中放入元素时,如果该队列已满,则线程被阻塞。而取元素时,如果该队列已空,则该线程被阻塞。
程序的两个线程通过交替向BlockingQueue中放入元素、取出元素,即可很好地控制线程的通信。

4.使用管道流进行线程通信(少用)

实际上由于两个线程属于同一个进程,它们可以非常方便地共享数据,因此很少需要使用管道流进行通信。
分享到:
评论

相关推荐

    多线程之间的线程通信

    "多线程之间的线程通信"是确保多个线程协同工作、避免数据不一致性和提高程序效率的关键概念。在本话题中,我们将深入探讨线程通信的原理、方法,以及潜在的危险。 首先,线程通信是指在一个进程中,不同的线程之间...

    多线程通信ThreadDemo

    2. **共享资源**:在多线程环境中,多个线程可能会访问同一块内存空间,即共享资源。这可能导致数据竞争和不一致的状态,因此需要有效的通信机制来协调线程的执行顺序。 3. **线程通信方法**: - **wait() 和 ...

    java多线程通信图解

    一张图方便理解和掌握java 多线程之间通信的实质 java 多线程 其实就是每个线程都拥有自己的内存空间,多线程之间的通信,比例A线程修改了主内存(main方法的线程)变量,需要把A线程修改的结果同步到主线程中,...

    qt 中 多线程tcp通信

    首先,标题"qt 中 多线程tcp通信"表明我们要在Qt环境中实现TCP(Transmission Control Protocol)的多线程通信。TCP是一种面向连接的、可靠的传输协议,确保数据的顺序传输和错误检查。在多线程环境下,我们可以将...

    计算机网络多线程通信简例

    本文将深入探讨计算机网络中的多线程通信,以Java编程语言为例,结合"MT_WebServer"这一文件,来阐述如何实现一个简单的多线程Web服务器。 首先,多线程是操作系统中并发执行的两个或多个线程,它们共享同一内存...

    VS2017实现Tcp socket多线程通信(C++)

    在本文中,我们将深入探讨如何使用Visual Studio 2017和C++来实现TCP套接字的多线程通信。TCP(传输控制协议)是一种面向连接、可靠的、基于字节流的通信协议,广泛应用于互联网上的各种服务。多线程技术则允许我们...

    c#编写串口通讯代码 多线程实现.rar_C#串口_c# 串口多线程_c#多线程_串口多线程_串口通信

    串口通信的实现,编程环境为C#,实现技术采用了多线程方式

    C++实现多线程通信

    在C++编程中,多线程通信是并发...理解并熟练掌握这些概念和工具,对于编写高效、稳定的多线程程序至关重要。在实际应用中,应根据具体需求选择合适的同步机制,并确保正确使用,以防止出现数据不一致和死锁等问题。

    多线程通信和等待机制.docx

    多线程通信和等待机制是多线程编程中一个重要的概念,它们都是基于线程之间的同步和协作来实现的。其中,wait()和notify()方法是Java语言中实现多线程通信和等待机制的两个核心方法。 wait()方法是Object类的一个...

    socket多线程通信源码

    总的来说,Socket多线程通信是一种强大的网络编程技术,它结合了Socket的网络通信能力和多线程的并行处理能力,能够有效地处理大量并发的客户端连接,提升服务的响应速度和效率。理解并熟练掌握这一技术,对于任何...

    多线程通信读写文件

    在编程领域,多线程通信是提升程序效率和并发能力的重要技术。特别是在处理大量数据时,如读写文件,多线程可以同时执行不同的任务,从而显著提高整体性能。本项目着重探讨如何在多线程环境中实现安全有效的文件读写...

    多线程udp通信

    在IT领域,多线程UDP通信是一个重要的主题,特别是在开发高效、实时的网络应用程序时。在Windows Forms(Winform)环境中,多线程技术结合用户界面(UI)和网络通信可以提升程序性能,避免UI线程阻塞,提高用户体验...

    基于MFC开发的多线程串口通信上位机

    **三、多线程技术** 在开发串口通信上位机时,多线程技术是必不可少的。多线程允许程序同时执行多个任务,提高程序的并发性和响应性。在MFC中,可以使用CWinThread类创建新的线程。每个线程可以独立处理读取串口...

    JAVA多线程通信学习_服务器多线程通信_

    在Java编程中,多线程通信是构建高效并发应用程序的关键技术。服务器多线程通信尤其重要,因为它允许服务器同时处理多个客户端请求,提高系统资源利用率并优化响应时间。本篇文章将深入探讨Java中的多线程通信,以及...

    多线程之间消息通信

    在计算机编程中,多线程是并发执行任务的一种方式,特别是在多核...通过对"MultiThread7"这个示例的学习,开发者可以更深入地理解Windows下的线程通信机制,并将其应用到自己的项目中,提升软件的性能和用户体验。

    控制台多线程通信 c++ winsock技术

    在C++编程中,实现控制台多线程通信通常涉及到并发处理和网络编程。Winsock是Windows操作系统中用于网络通信的API(应用程序接口),它提供了一套标准的接口供开发者使用,使得在C++中实现TCP/IP协议栈的程序变得...

    串口通信及多线程之间通信

    这些代码可能会展示如何创建和配置QSerialPort对象,以及如何使用QThread和信号槽进行多线程间的通信。通过阅读和学习这些代码,开发者可以更深入地理解如何在实际项目中应用串口通信和多线程技术。 总之,QT5的...

    c++ 多线程编程之三----线程间通讯

    C++ 多线程编程之三----线程间通讯 C++ 多线程编程中,线程间通讯是非常重要的一部分。线程间通讯可以让不同的线程之间进行信息传递,实现协作和同步。在多线程编程中,线程间通讯可以使用全局变量、自定义消息等...

    Delphi API 串口通信 多线程例子.rar

    在"Delphi API 串口通信 多线程例子.rar"这个压缩包中,可能包含了一个示例项目,展示了如何使用Delphi的API和多线程技术实现串口通信。文件名"codefans.net"可能指的是一个代码分享网站,或者是一个特定的源代码...

    C#,socket(多线程)通信

    利用多线程实现C#中socket网络通信模块,具体最大承受多少个客户端还不是很清楚,但是20个绝对没问题

Global site tag (gtag.js) - Google Analytics