`
1028826685
  • 浏览: 938763 次
  • 性别: Icon_minigender_1
  • 来自: 重庆
社区版块
存档分类

Condition-线程通信更高效的方式

 
阅读更多

  那么引入本篇的主角,Condition,Condition 将 Object 监视器方法(wait、notify 和 notifyAll)分解成截然不同的对象,以便通过将这些对象与任意 Lock 实现组合使用,为每个对象提供多个等待 set (wait-set)。其中,Lock 替代了 synchronized 方法和语句的使用,Condition 替代了 Object 监视器方法的使用。下面将之前写过的一个线程通信的例子替换成用Condition实现(Java线程(三)),代码如下:

 

[java] view plain copy
 
 print?在CODE上查看代码片派生到我的代码片
  1. public class ThreadTest2 {  
  2.     public static void main(String[] args) {  
  3.         final Business business = new Business();  
  4.         new Thread(new Runnable() {  
  5.             @Override  
  6.             public void run() {  
  7.                 threadExecute(business, "sub");  
  8.             }  
  9.         }).start();  
  10.         threadExecute(business, "main");  
  11.     }     
  12.     public static void threadExecute(Business business, String threadType) {  
  13.         for(int i = 0; i < 100; i++) {  
  14.             try {  
  15.                 if("main".equals(threadType)) {  
  16.                     business.main(i);  
  17.                 } else {  
  18.                     business.sub(i);  
  19.                 }  
  20.             } catch (InterruptedException e) {  
  21.                 e.printStackTrace();  
  22.             }  
  23.         }  
  24.     }  
  25. }  
  26. class Business {  
  27.     private boolean bool = true;  
  28.     private Lock lock = new ReentrantLock();  
  29.     private Condition condition = lock.newCondition();   
  30.     public /*synchronized*/ void main(int loop) throws InterruptedException {  
  31.         lock.lock();  
  32.         try {  
  33.             while(bool) {                 
  34.                 condition.await();//this.wait();  
  35.             }  
  36.             for(int i = 0; i < 100; i++) {  
  37.                 System.out.println("main thread seq of " + i + ", loop of " + loop);  
  38.             }  
  39.             bool = true;  
  40.             condition.signal();//this.notify();  
  41.         } finally {  
  42.             lock.unlock();  
  43.         }  
  44.     }     
  45.     public /*synchronized*/ void sub(int loop) throws InterruptedException {  
  46.         lock.lock();  
  47.         try {  
  48.             while(!bool) {  
  49.                 condition.await();//this.wait();  
  50.             }  
  51.             for(int i = 0; i < 10; i++) {  
  52.                 System.out.println("sub thread seq of " + i + ", loop of " + loop);  
  53.             }  
  54.             bool = false;  
  55.             condition.signal();//this.notify();  
  56.         } finally {  
  57.             lock.unlock();  
  58.         }  
  59.     }  
  60. }  

        在Condition中,用await()替换wait(),用signal()替换notify(),用signalAll()替换notifyAll(),传统线程的通信方式,Condition都可以实现,这里注意,Condition是被绑定到Lock上的,要创建一个Lock的Condition必须用newCondition()方法。

 

        这样看来,Condition和传统的线程通信没什么区别,Condition的强大之处在于它可以为多个线程间建立不同的Condition,下面引入API中的一段代码,加以说明。

 

[java] view plain copy
 
 print?在CODE上查看代码片派生到我的代码片
  1. class BoundedBuffer {  
  2.    final Lock lock = new ReentrantLock();//锁对象  
  3.    final Condition notFull  = lock.newCondition();//写线程条件   
  4.    final Condition notEmpty = lock.newCondition();//读线程条件   
  5.   
  6.    final Object[] items = new Object[100];//缓存队列  
  7.    int putptr/*写索引*/, takeptr/*读索引*/, count/*队列中存在的数据个数*/;  
  8.   
  9.    public void put(Object x) throws InterruptedException {  
  10.      lock.lock();  
  11.      try {  
  12.        while (count == items.length)//如果队列满了   
  13.          notFull.await();//阻塞写线程  
  14.        items[putptr] = x;//赋值   
  15.        if (++putptr == items.length) putptr = 0;//如果写索引写到队列的最后一个位置了,那么置为0  
  16.        ++count;//个数++  
  17.        notEmpty.signal();//唤醒读线程  
  18.      } finally {  
  19.        lock.unlock();  
  20.      }  
  21.    }  
  22.   
  23.    public Object take() throws InterruptedException {  
  24.      lock.lock();  
  25.      try {  
  26.        while (count == 0)//如果队列为空  
  27.          notEmpty.await();//阻塞读线程  
  28.        Object x = items[takeptr];//取值   
  29.        if (++takeptr == items.length) takeptr = 0;//如果读索引读到队列的最后一个位置了,那么置为0  
  30.        --count;//个数--  
  31.        notFull.signal();//唤醒写线程  
  32.        return x;  
  33.      } finally {  
  34.        lock.unlock();  
  35.      }  
  36.    }   
  37.  }  

        这是一个处于多线程工作环境下的缓存区,缓存区提供了两个方法,put和take,put是存数据,take是取数据,内部有个缓存队列,具体变量和方法说明见代码,这个缓存区类实现的功能:有多个线程往里面存数据和从里面取数据,其缓存队列(先进先出后进后出)能缓存的最大数值是100,多个线程间是互斥的,当缓存队列中存储的值达到100时,将写线程阻塞,并唤醒读线程,当缓存队列中存储的值为0时,将读线程阻塞,并唤醒写线程,下面分析一下代码的执行过程:

 

        1. 一个写线程执行,调用put方法;

        2. 判断count是否为100,显然没有100;

        3. 继续执行,存入值;

        4. 判断当前写入的索引位置++后,是否和100相等,相等将写入索引值变为0,并将count+1;

        5. 仅唤醒读线程阻塞队列中的一个;

        6. 一个读线程执行,调用take方法;

        7. ……

        8. 仅唤醒写线程阻塞队列中的一个。

        这就是多个Condition的强大之处,假设缓存队列中已经存满,那么阻塞的肯定是写线程,唤醒的肯定是读线程,相反,阻塞的肯定是读线程,唤醒的肯定是写线程,那么假设只有一个Condition会有什么效果呢,缓存队列中已经存满,这个Lock不知道唤醒的是读线程还是写线程了,如果唤醒的是读线程,皆大欢喜,如果唤醒的是写线程,那么线程刚被唤醒,又被阻塞了,这时又去唤醒,这样就浪费了很多时间。

        本文来自:高爽|Coder,原文地址:http://blog.csdn.net/ghsau/article/details/7481142,转载请注明。

分享到:
评论

相关推荐

    多线程之间的线程通信

    总的来说,理解和掌握多线程之间的线程通信是编写高效、可靠并发程序的基础。通过合理设计和使用各种通信机制,我们可以创建出能够充分利用系统资源、处理复杂逻辑的多线程应用程序。在实际项目中,应始终关注线程...

    Java的多线程-线程间的通信.doc

    在Java多线程编程中,线程间的通信是非常重要的概念,用于协调多个并发执行的任务。线程的状态转换是理解线程通信的基础,主要包括四个...因此,理解并熟练掌握Java中的线程通信机制对于编写高效的多线程程序至关重要。

    用成员变量进行线程通信.rar_线程通信

    线程通信是多线程编程中的一个重要概念,它是指在并发执行的多个线程之间交换信息的方式。在Java等编程语言中,线程通信通常用于解决共享数据的问题,确保线程间的协作和同步,防止数据竞争和死锁等问题。本资料“用...

    进程线程通信,线程同步,异步,进程通信经典进程间通信.7z

    与线程通信相比,进程间通信面临的挑战更多,因为它们拥有独立的内存空间。常见的进程间通信方式包括管道(Pipe)、消息队列、共享内存、套接字(Socket)、命名管道、信号量等。例如,套接字通信广泛应用于分布式...

    Java 线程通信示例 源代码

    在Java编程中,多线程通信是一个至关重要的概念,特别是在设计高效的并发应用程序时。这个"Java线程通信示例源代码"很可能包含了演示如何在不同线程之间共享数据和协调执行顺序的实例。线程通信主要涉及两个核心概念...

    Java编程中实现Condition控制线程通信

    Java中的Lock接口及其实现,如ReentrantLock,提供了更高级的线程通信机制,其中包括Condition接口。 Condition接口是Java并发包java.util.concurrent.locks的一部分,它允许我们创建特定于锁的等待集合。相比于...

    C++实现多线程通信

    在C++编程中,多线程通信是并发执行任务时必不可少的一个环节,它涉及到线程间的同步和数据共享。在本篇文章中,我们将深入探讨如何在C++中实现多线程通信,以及相关的同步机制和数据交换策略。 一、线程创建与管理...

    15-linux线程专题讲座-王保明.rar

    在Linux操作系统中,线程是进程的一个执行单元,它共享同一进程的地址空间和其他资源,因此线程间的通信和同步非常高效。本专题讲座由专家王保明主讲,深入探讨了Linux线程的相关概念、创建与管理、同步机制以及在...

    多线程的那点儿事-线程编码

    总结起来,多线程的那点儿事涉及到线程的创建与管理、同步与通信、线程安全以及资源优化等多个方面,理解和掌握这些知识点对于编写高效、稳定的并发程序至关重要。实际开发中,我们需要结合具体语言特性和应用场景,...

    图书管理线程通信问题

    在IT领域,线程通信是多...理解并正确使用各种线程通信机制,可以保证系统的高效、稳定和数据一致性。在实际开发过程中,我们需要根据具体需求选择合适的方法,并充分考虑并发情况下的线程安全,避免数据竞争和死锁。

    vc线程通信实现计时器

    在VC++编程环境中,线程通信是多线程应用程序中不可或缺的一部分,特别是在需要同步或定时操作的场景下。本文将深入探讨如何利用VC++实现线程间的通信,并以计时器为例来阐述这一过程。 首先,理解线程通信的基本...

    思维导图-多线程进阶总结02

    Java中提供了多种机制来实现线程通信,如: 1. **wait()、notify() 和 notifyAll()**:这组方法是Object类的成员,用于线程间同步。一个线程调用wait()后会释放锁并等待,直到其他线程调用notify()或notifyAll()...

    多线程_sometimelrz_examine9j3_多线程通信_

    在IT领域,多线程通信是一项关键的技术,尤其在客户端-服务器架构中,它使得程序能够同时处理多个请求,提高系统效率和响应速度。本文将深入探讨多线程通信的概念、重要性以及实现方法。 首先,多线程是指在一个...

    C++ 多线程通信方式简介并结合生产者-消费者模式代码实现

    本文将深入探讨C++中的多线程通信方式,并结合经典的生产者-消费者模式来阐述其实现。 一、C++多线程基础 C++11引入了标准库`&lt;thread&gt;`,提供了对多线程的支持。创建线程的基本方法是通过`std::thread`类,如下所示...

    430.428.JAVA基础教程_多线程-线程的生命周期(430).rar

    理解并熟练掌握Java线程的生命周期对于编写高效、安全的多线程程序至关重要,尤其是在处理高并发场景时。合理地设计和管理线程能够提高程序的性能,避免死锁、活锁和饥饿等问题,从而确保程序的稳定性和可靠性。

    Python线程协作threading.Condition实现过程解析

    这种机制使得线程能够以有序和可控的方式进行通信,避免竞态条件和死锁。 在示例中,我们创建了两个线程,一个是`Boy`,另一个是`Girl`,它们都持有一个`condition`对象。每个线程在运行时会进入一个`with self....

    操作系统中多线程之间通信

    在操作系统中,有多种实现线程通信的方式: 1. **信号量(Semaphore)**:信号量是一种计数器,可以用于限制同时访问某个资源的线程数量。它可以是二进制信号量(只能取0或1,类似互斥锁)或计数信号量(可取大于1...

    Linux系统编程-(pthread)线程通信(条件变量).pdf

    【Linux系统编程——pthread线程通信(条件变量)】 在多线程编程中,线程间的通信是非常重要的,条件变量(Condition Variables)是POSIX线程(pthread)库提供的一种同步机制,它允许线程在特定条件满足时才能继续...

    使用全局对象进行线程间的通信

    线程通信是指不同的线程间交换信息或同步执行的过程,这对于实现并发操作和协调不同任务至关重要。本篇文章将深入探讨如何在VC++ 2008中利用全局变量进行线程间的通信。 首先,我们需要了解全局变量的作用。全局...

Global site tag (gtag.js) - Google Analytics