在并发编程中,我们必须考虑的问题时如何在两个线程间进行通讯。这里的通讯指的是不同的线程之间如何交换信息。

目前有两种方式:

1、共享内存

2、消息传递(actor 模型)

共享内存:

共享内存这种方式比较常见,我们经常会设置一个共享变量。然后多个线程去操作同一个共享变量。从而达到线程通讯的目的。例如,我们使用多个线程去执行页面抓取任务,我们可以使用一个共享变量count来记录任务完成的数量。每当一个线程完成抓取任务,会在原来的count上执行加1操作。这样每个线程都可以通过获取这个count变量来获得当前任务的完成情况。当然必须要考虑的是共享变量的同步问题,这也共享内存容易出错的原因所在。

这种通讯模型中,不同的线程之间是没有直接联系的。都是通过共享变量这个“中间人”来进行交互。而这个“中间人”必要情况下还需被保护在临界区内(加锁或同步)。由此可见,一旦共享变量变得多起来,并且涉及到多种不同线程对象的交互,这种管理会变得非常复杂,极容易出现死锁等问题。

消息传递

消息传递方式采取的是线程之间的直接通信,不同的线程之间通过显式的发送消息来达到交互目的。消息传递最有名的方式应该是actor模型了。在这种模型下,一切都是actor,所有的actor之间的通信都必须通过传递消息才能达到。每个actor都有一个收件箱(消息队列)用来保存收到其他actor传递来的消息。actor自己也可以给自己发送消息。这才是面向对象的精髓啊!

这种模型看起来比共享内存模型要复杂。但是一旦碰到复杂业务的话,actor模型的优势就体现出来了。我们还是以刚才多线程抓取网站为例子看一下在这种模型下如何去解决。

首先我们定义一个统计actor用来统计任务完成量。然后把多个网址(消息方式)发给多个抓取actor,抓取actor处理完任务后发送消息通知统计actor任务完成,统计actor对自己保存的变量count(这个只有统计actor才能看到)加一。

最后让我们来总结一下这两种通讯模式:

并发模型 通信机制 同步机制
共享内存
线程之间共享程序的公共状态,线程之间通过写-读内存中的公共状态来隐式进行通信。
同步是显式进行的。程序员必须显式指定某个方法或某段代码需要在线程之间互斥执行。
消息传递(actor)
线程之间没有公共状态,线程之间必须通过明确的发送消息来显式进行通信。
由于消息的发送必须在消息的接收之前,因此同步是隐式进行的。

线程通信机制:共享内存 VS 消息传递的更多相关文章

  1. JAVA多线程提高二:传统线程的互斥与同步&传统线程通信机制

    本文主要是回顾线程之间互斥和同步,以及线程之间通信,在最开始没有juc并发包情况下,如何实现的,也就是我们传统的方式如何来实现的,回顾知识是为了后面的提高作准备. 一.线程的互斥 为什么会有线程的互斥 ...

  2. Java笔记1 : 在生产者消费者模式中,线程通信与共享数据,死锁问题与解决办法

    本例定义了4个类,这里说一下,方便下面讲解.分别是Product(产品),Producer(生产者),Consumer(消费者), Test(测试类). 多线程之间通信与共享数据只要引用同一内存区域就 ...

  3. 【VxWorks系列】任务间同步与通信之共享内存

    在开始之前先说明三个概念,任务间的同步,互斥,通信. 同步,是指一个任务等待某个条件发生,而另外一个任务引发这个条件后,等待的任务会被触发执行相应的处理.这就是一个任务与另一任务之间的同步控制. 互斥 ...

  4. linux进程通信之共享内存

    共享内存同意两个或多个进程共享一给定的存储区,由于数据不须要来回复制,所以是最快的一种进程间通信机制.共享内存能够通过mmap()映射普通文件(特殊情况下还能够採用匿名映射)机制实现,也能够通过系统V ...

  5. linux进程间的通信之 共享内存

    一.共享内存介绍 共享内存是三个IPC(Inter-Process Communication)机制中的一个. 它允许两个不相关的进程访问同一个逻辑内存. 共享内存是在两个正在进行的进程之间传递数据的 ...

  6. Linux进程通信之共享内存实现生产者/消费者模式

    共享内存 共享内存是内核为进程创建的一个特殊内存段,它将出现在进程自己的地址空间中,其它进程可以将同一段共享内存连接(attach)到自己的地址空间.这是最快的进程间通信方式,但是不提供任何同步功能( ...

  7. linux 进程通信之 共享内存

    共享内存是被多个进程共享的一部分物理内存.共享内存是进程间共享数据的一种最快的方法.一个进程向共享内存区域写入了数据,共享这个内存区域的全部进程就能够立马看到当中的内容. 关于共享内存使用的API k ...

  8. Linux 进程通信(共享内存区)

    共享内存是由内核出于在多个进程间交换信息的目的而留出的一块内存区(段). 如果段的权限设置恰当,每个要访问该段内存的进程都可以把它映像到自己的私有地址空间中. 如果一个进程更新了段中的数据,其他进程也 ...

  9. java 并发性和多线程 -- 读感 (二 线程间通讯,共享内存的机制)

    参考文章:http://ifeve.com/java-concurrency-thread-directory/ 其中的竞态,线程安全,内存模型,线程间的通信,java ThreadLocal类小节部 ...

随机推荐

  1. Thread Join()的用法

    Java Thread类有个 join() 方法,先前一直不知道是怎么用的,直到看到这篇文章.http://auguslee.iteye.com/blog/1292203 Java Thread中, ...

  2. dubbo(soa分布式)与cobar(mysql分布式)

    http://www.jianshu.com/p/0dde591f21d0 (Dubbo编译不是个顺利的事) Cobar是提供关系型数据库(MySQL)分布式服务的中间件,它可以让传统的数据库得到良好 ...

  3. [PWA] 5. Hijacking one type of request

    Previously we saw how to Hijacking all the reqest, but this is not useful. So now we want to see how ...

  4. 3 Ways to Preload Images with CSS, JavaScript, or Ajax---reference

    Preloading images is a great way to improve the user experience. When images are preloaded in the br ...

  5. POJ 2049 Finding Nemo

    Finding Nemo Time Limit: 2000MS   Memory Limit: 30000K Total Submissions: 8631   Accepted: 2019 Desc ...

  6. Phonegap 极光推送api 服务器端推送代码

    .net 版本 极光推送 后台接口 HttpWebResponseUtility类 using System; using System.Collections.Generic; using Syst ...

  7. asp.net基础概念总结

    1  什么是asp.net?asp.net是一种编程语言吗? asp.net是Microsoft公司推出的新一代建立动态web应用程序的开发平台,是一种建立动态web应用程序的新技术. 不是,asp. ...

  8. Oracle NULLIF函数

    Oracle NULLIF函数 Oracle NULLIF函数语法为NULLIF(表达式1,表达式2),如果表达式1和表达式2相等则返回空值,如果表达式1和表达式2不相等则返回表达式1的结果. 注意: ...

  9. Apache下Worker模式MPM参数分析

    我的worker.c配置如下:<IfModule mpm_worker_module> ServerLimit   32 ThreadLimit   128 StartServers   ...

  10. CSS注释代码

    就像在Html的注释一样,在CSS中也有注释语句:用/*注释语句*/来标明(Html中使用<!--注释语句-->).就像下面代码: 示例: <!DOCTYPE HTML> &l ...