欢迎来到天天文库
浏览记录
ID:14442444
大小:226.50 KB
页数:18页
时间:2018-07-28
《java 和 scala 并发性基础》由会员上传分享,免费在线阅读,更多相关内容在行业资料-天天文库。
1、JVM并发性:Java和Scala并发性基础处理器速度数十年来一直持续快速发展,并在世纪交替之际走到了终点。从那时起,处理器制造商更多地是通过增加核心来提高芯片性能,而不再通过增加时钟速率来提高芯片性能。多核系统现在成为了从手机到企业服务器等所有设备的标准,而这种趋势可能继续并有所加速。开发人员越来越需要在他们的应用程序代码中支持多个核心,这样才能满足性能需求。在本系列文章中,您将了解一些针对Java和Scala语言的并发编程的新方法,包括Java如何将Scala和其他基于JVM的语言中已经探索出来的理念结合在一起。第一期文章将介绍一些背景,通过介绍Jav
2、a7和Scala的一些最新技术,帮助了解JVM上的并发编程的全景。您将了解如何使用Java ExecutorService 和 ForkJoinPool 类来简化并发编程。还将了解一些将并发编程选项扩展到纯Java中的已有功能之外的基本Scala特性。在此过程中,您会看到不同的方法对并发编程性能有何影响。后续几期文章将会介绍Java8中的并发性改进和一些扩展,包括用于执行可扩展的Java和Scala编程的 Akka 工具包。Java并发性支持在Java平台诞生之初,并发性支持就是它的一个特性,线程和同步的实现为它提供了超越其他竞争语言的优势。Scala基于
3、Java并在JVM上运行,能够直接访问所有Java运行时(包括所有并发性支持)。所以在分析Scala特性之前,我首先会快速回顾一下Java语言已经提供的功能。Java线程基础在Java编程过程中创建和使用线程非常容易。它们由 java.lang.Thread 类表示,线程要执行的代码为 java.lang.Runnable 实例的形式。如果需要的话,可以在应用程序中创建大量线程,您甚至可以创建数千个线程。在有多个核心时,JVM使用它们来并发执行多个线程;超出核心数量的线程会共享这些核心。Java5:并发性的转折点Java从一开始就包含对线程和同步的支持。但
4、在线程间共享数据的最初规范不够完善,这带来了Java5的Java语言更新中的重大变化(JSR-133)。JavaLanguageSpecificationforJava5更正并规范化了 synchronized和 volatile 操作。该规范还规定不变的对象如何使用多线程。(基本上讲,只要在执行构造函数时不允许引用“转义”,不变的对象始终是线程安全的。)以前,线程间的交互通常需要使用阻塞的 synchronized 操作。这些更改支持使用 volatile 在线程间执行非阻塞协调。因此,在Java5中添加了新的并发集合类来支持非阻塞操作—这与早期仅支持阻
5、塞的线程安全方法相比是一项重大改进。线程操作的协调难以让人理解。只要从程序的角度让所有内容保持一致,Java编译器和JVM就不会对您代码中的操作重新排序,这使得问题变得更加复杂。例如:如果两个相加操作使用了不同的变量,编译器或JVM可以安装与指定的顺序相反的顺序执行这些操作,只要程序不在两个操作都完成之前使用两个变量的总数。这种重新排序操作的灵活性有助于提高Java性能,但一致性只被允许应用在单个线程中。硬件也有可能带来线程问题。现代系统使用了多种缓存内存级别,一般来讲,不是系统中的所有核心都能同样看到这些缓存。当某个核心修改内存中的一个值时,其他核心可能
6、不会立即看到此更改。由于这些问题,在一个线程使用另一个线程修改的数据时,您必须显式地控制线程交互方式。Java使用了特殊的操作来提供这种控制,在不同线程看到的数据视图中建立顺序。基本操作是,线程使用 synchronized 关键字来访问一个对象。当某个线程在一个对象上保持同步时,该线程将会获得此对象所独有的一个锁的独占访问。如果另一个线程已持有该锁,等待获取该锁的线程必须等待,或者被阻塞,直到该锁被释放。当该线程在一个synchronized 代码块内恢复执行时,Java会保证该线程可以“看到了”以前持有同一个锁的其他线程写入的所有数据,但只是这些线程通
7、过离开自己的 synchronized 锁来释放该锁之前写入的数据。这种保证既适用于编译器或JVM所执行的操作的重新排序,也适用于硬件内存缓存。一个 synchronized 块的内部是您代码中的一个稳定性孤岛,其中的线程可依次安全地执行、交互和共享信息。在变量上对 volatile 关键字的使用,为线程间的安全交互提供了一种稍微较弱的形式。synchronized 关键字可确保在您获取该锁时可以看到其他线程的存储,而且在您之后,获取该锁的其他线程也会看到您的存储。volatile 关键字将这一保证分解为两个不同的部分。如果一个线程向 volatile 变
8、量写入数据,那么首先将会擦除它在这之前写入的数据。如果某个线程读取
此文档下载收益归作者所有