一直以来,多线程代码是服务器开发人员的毒药(问问Oracle的Java语言架构师和并行开发大师Brian Goetz)。Java的核心库不断加入各种复杂的用法来减少访问共享资源时的线程等待时间。其中之一就是经典的读写锁(ReadWriteLock),它让你把代码分成两部分:需要互斥的写操作和不需要互斥的读操作。

表面上看起来很不错。问题是读写锁有可能是极慢的(最多10倍),这已经和它的初衷相悖了。Java 8引入了一种新的读写锁——叫做时间戳锁。好消息是这个家伙真的非常快。坏消息是它使用起来更复杂,有更多的状态需要处理。并且它是不可重入的,这意味着一个线程有可能跟自己死锁。

时间戳锁有一种“乐观”模式,在这种模式下每次加锁操作都会返回一个时间戳作为某种权限凭证;每次解锁操作都需要提供它对应的时间戳。如果一个线程在请求一个写操作锁的时候,这个锁碰巧已经被一个读操作持有,那么这个读操作的解锁将会失效(因为时间戳已经失效)。这个时候应用程序需要从头再来,也许要使用悲观模式的锁(时间戳锁也有实现)。你需要自己搞定这一切,并且一个时间戳只能解锁它对应的锁——这一点必须非常小心。

下面我们来看一下这种锁的实例——

long stamp = lock.tryOptimisticRead(); // 非阻塞路径——超级快

work(); // 我们希望不要有写操作在这时发生

if (lock.validate(stamp)){

//成功!没有写操作干扰

}

else {

//肯定同时有另外一个线程获得了写操作锁,改变了时间戳

//懒汉说——我们切换到开销更大的锁吧

stamp = lock.readLock(); //这是传统的读操作锁,会阻塞

try {

//现在不可能有写操作发生了

work();

}

finally {

lock.unlock(stamp); // 使用对应的时间戳解锁

}

}

并发加法器

Java 8另一个出色的功能是并发“加法器”,它对大规模运行的代码尤其有意义。一种最基本的并发模式就是对一个计数器的读写。就其本身而言,现今处理这个问题有很多方法,但是没有一种能比Java 8提供的方法高效或优雅。

到目前为止,这个问题是用原子类(Atomics)来解决的,它直接利用了CPU的“比较并交换”指令(CAS)来测试并设置计数器的值。问题在于当一条CAS指令因为竞争而失败的时候,AtomicInteger类会死等,在无限循环中不断尝试CAS指令,直到成功为止。在发生竞争概率很高的环境中,这种实现被证明是非常慢的。

来看Java 8的LongAdder。这一系列类为大量并行读写数值的代码提供了方便的解决办法。使用超级简单。只要初始化一个LongAdder对象并使用它的add()和intValue()方法来累加和采样计数器。

这和旧的Atomic类的区别在于,当CAS指令因为竞争而失败时,Adder不会一直占着CPU,而是为当前线程分配一个内部cell对象来存储计数器的增量。然后这个值和其他待处理的cell对象一起被加到intValue()的结果上。这减少了反复使用CAS指令或阻塞其他线程的可能性。

如果你问你自己,什么时候应该用并发加法器而不是原子类来管理计数器?简单的答案就是——一直这么做。

并行排序

正像并发加法器能加速计数一样,Java 8还实现了一种简洁的方法来加速排序。这个秘诀很简单。你不再这么做:

Array.sort(myArray);

而是这么做:

Arrays.parallelSort(myArray);

这会自动把目标数组分割成几个部分,这些部分会被放到独立的CPU核上去运行,再把结果合并起来。这里唯一需要注意的是,在一个大量使用多线程的环境中,比如一个繁忙的Web容器,这种方法的好处就会减弱(降低90%以上),因为越来越多的CPU上下文切换增加了开销。

切换到新的日期接口

Java 8引入了全新的date-time接口。当前接口的大多数方法都已被标记为deprecated,你就知道是时候推出新接口了。新的日期接口为Java核心库带来了易用性和准确性,而以前只能用Joda time才能达到这样的效果(译者注:Joda time是一个第三方的日期库,比Java自带的库更友好更易于管理)。

跟任何新接口一样,好消息是接口变得更优雅更强大。但不幸的是还有大量的代码在使用旧接口,这个短时间内不会有改变。

为了衔接新旧接口,历史悠久的Date类新增了toInstant()方法,用于把Date转换成新的表示形式。当你既要享受新接口带来的好处,又要兼顾那些只接受旧的日期表示形式的接口时,这个方法会显得尤其高效。

控制操作系统进程

想在你的代码里启动一个操作系统进程,通过JNI调用就能完成——但这个东西总令人一知半解,你很有可能得到一个意想不到的结果,并且一路伴随着一些很糟糕的异常。

即便如此,这是无法避免的事情。但进程还有一个讨厌的特性就是——它们搞不好就会变成僵尸进程。目前从Java中运行进程带来的问题是,进程一旦启动就很难去控制它。

为了帮我们解决这个问题,Java 8在Process类中引入了三个新的方法

destroyForcibly——结束一个进程,成功率比以前高很多。

isAlive——查询你启动的进程是否还活着。

重载了waitFor(),你现在可以指定等待进程结束的时间了。进程成功退出后这个接口会返回,超时的话也会返回,因为你有可能要手动终止它。

这里有两个关于如何使用这些新方法的好例子——如果进程没有在规定时间内退出,终止它并继续往前走。

if (process.wait(MY_TIMEOUT, TimeUnit.MILLISECONDS)){

//成功

}else {

process.destroyForcibly();

}

在你的代码结束前,确保所有的进程都已退出。僵尸进程会逐渐耗尽系统资源。

for (Process p : processes) {

if (p.isAlive()) {

p.destroyForcibly();

}

}

精确的数字运算

数字溢出会导致一些讨厌的bug,因为它本质上不会出错。在一些系统中,整型值不停地增长(比如计数器),溢出的问题就尤为严重。在这些案例里面,产品在演进阶段运行得很好,甚至商用后的很长时间内也没问题,但最终会出奇怪的故障,因为运算开始溢出,产生了完全无法预料的值。

为了解决这个问题,Java 8为Math类添加了几个新的“精确型”方法,以便保护重要的代码不受溢出的影响,它的做法是当运算超过它的精度范围的时候,抛出一个未检查的ArithmeticException异常。

int safeC = Math.multiplyExact(bigA, bigB);

// 如果结果超出+-2^31,就会抛出ArithmeticException异常

唯一不好的地方就是你必须自己找出可能产生溢出的代码。无论如何,没有什么自动的解决方案。但我觉得有这些接口总比没有好。

安全的随机数发生器

在过去几年中Java一直因为安全漏洞而饱受诟病。无论是否合理,Java已经做了大量工作来加强虚拟机和框架层,使之免受攻击。如果随机数来源于随机性不高的种子,那么那些用随机数来产生密钥或者散列敏感信息的系统就更易受攻击。

到目前为止,随机数发生算法由开发人员来决定。但问题是,如果你想要的算法依赖于特定的硬件、操作系统、虚拟机,那你就不一定能实现它。这种情况下,应用程序倾向于使用更弱的默认发生器,这就使他们暴露在更大的风险下了。

Java 8添加了一个新的方法叫SecureRandom.getInstanceStrong(),它的目标是让虚拟机为你选择一个安全的随机数发生器。如果你的代码无法完全掌控操作系统、硬件、虚拟机(如果你的程序部署到云或者PaaS上,这是很常见的),我建议你认真考虑一下使用这个接口。

可选引用

空指针就像“踢到脚趾”一样——从你学会走路开始就伴随着你,无论现在你有多聪明——你还是会犯这个错。为了帮助解决这个老问题,Java 8引入了一个新模板叫Optional。

这个模板是从Scala和Hashkell借鉴来的,用于明确声明传给函数或函数返回的引用有可能是空的。有了它,过度依赖旧文档或者看过的代码经常变动的人,就不需要去猜测某个引用是否可能为空。

Optional tryFindUser(int userID) {

void processUser(User user, Optional shoppingCart) {

Optional模板有一套函数,使得采样它更方便,比如isPresent()用来检查这个值是不是非空,或者ifPresent()你可以传递一个Lambda函数过去,如果isPresent()返回true,这个Lambda函数就会被执行。不好的地方就跟Java 8的新日期接口一样,等这种模式逐渐流行,渗透到我们使用的库中和日常设计中,需要时间和工作量。

value.ifPresent(System.out::print);

上文内容不用于商业目的,如涉及知识产权问题,请权利人联系博为峰小编(021-64471599-8017),我们将立即处理。

java 8 什么软件_Java 8你了解多少呢?Java之被人遗忘的Java 8的八个功能相关推荐

  1. 用java制作心理测试软件_Java 程序员必备的10款开源工具

    Java世界中存在许多工具,从Eclipse,NetBeans和IntelliJ IDEA等著名的IDE开始到Java开发人员应该知道的JVM分析和监视工具,如JConsole,VisualVM,Ec ...

  2. Java西西软件_java环境配置软件

    java环境配置软件是一款非常好用的Java编程环境变量配置工具,初学JAVA 配置编程环境很多人摸不清怎么做,然后网络大神就写了一键配置省很多步骤,win10下测试成功通过,其它没有测试环境.有需要 ...

  3. java class 静态模块_Java API 最佳设计实践:在模块化和非模块化 Java 环境中使用...

    了解在设计 Java API 时应该运用的一些 API 设计实践.这些实践通常很有用,而且可确保 API 能在诸如 OSGi 和 Java Platform Module System (JPMS) ...

  4. Java低级编程软件_JAVA语言说低级语言吗

    高级语言:C.C++.Java.Python.Pascal.Lisp.Prolog.FoxPro.易语言等都是高级语言,相对于低级语言来说,高级语言采用易于识别和记忆的字符来作为关键字,也更接近人类的 ...

  5. java算术测试软件_Java——编写一个算术测试小软件

    问题描述: 编写一个算术测试小软件,用来训练小学生的算术能力.程序由3个类组成,其中Teacher类对象负责给出算术题目,并判断回答者的答案是否正确:ComputerFrame类对象提供的GUI界面看 ...

  6. 有关java的参考软件_Java的相关的排序实现(参考软件设计师教程)

    package com.liuxt.sort; import java.io.BufferedReader; import java.io.IOException; import java.io.In ...

  7. 翻译java语言的软件_java实现英文翻译程序

    本文实例为大家分享了java实现英文翻译程序的具体代码,供大家参考,具体内容如下 1.功能简介 将文本文件中的英文转换为对应的中文 词库如下: 源文件: 翻译后的文件: 输入源文件路径,将翻译后的内容 ...

  8. java开发 cad软件_java语言可以用于cad开发吗

    摘要:根据COM技术原理,本文利用AutoCAD2000提供的类型库,编写了一个演示例程:同时,详细介绍了应用Java语言进行AutoCAD二次开发的方法和思路. 关键字:二次开发,AutoCAD定制 ...

  9. java开发电脑软件_JAVA开发程序员,开发使用笔记本推荐?

    同 java 路过. 买笔记本,我们可以从以下几点来选购参考. "硬参数"CPU 内存 硬盘 显卡 "软参数"屏幕 重量 散热 那依次来按照顺序来介绍下. &q ...

最新文章

  1. c语言rank需要头文件吗,C++ std::rank用法及代码示例
  2. 旋转动画 rotate
  3. 4.1 基础-放苹果(整数划分)
  4. 历史回顾——NLP问题解决方案的演变史
  5. postman怎么传对象list_postman 传递json的参数里面带了List对象
  6. C语言课设----个人信息管理系统(包含学生成绩和消费记录)
  7. ADSL常见问题 经典故障
  8. python实现蒙特卡洛模拟_蒙特卡洛模拟(Python)深入教程
  9. 朋友公司年会需要一个抽奖程序,我花1小时给她写了一个...
  10. 公共场合的wifi 靠不住
  11. B站视频封面图片获取_CodingPark编程公园
  12. 适合运动时戴的蓝牙耳机有哪些、非常优秀的运动型蓝牙耳机推荐
  13. 使用计算机需要准备硬件和什么,当个人计算机需要使用ADSL访问Internet时,所需的基本硬件设施是什么?...
  14. 经典论文翻译导读之《A Bloat-Aware Design for Big Data Applications》
  15. ios 7 Launch Images改变屏幕尺寸
  16. MATLAB恢复编辑器窗口停靠
  17. Android SVGA动画
  18. pwn暑假练习,额额不能被落下太远
  19. 解决M1处理器款mac安装PR闪退问题 Premier 2020 Mac(已适配M1芯片,支持最新款M1芯片Mac)可稳定运行
  20. 中企海外周报 | 支付宝借力RiverPay进军欧洲健康品牌1600多家门店;汉能启用荷兰最大薄膜太阳能发电工业园...

热门文章

  1. swift闭包 notes http://www.gittielabs.com
  2. location.href使用方法总结
  3. UIScollerViewUIPageControl的一些使用方法
  4. xp网吧用母盘制作说明
  5. IoC~MVC3+EF+Autofac实现松耦合的系统架构 [转载]
  6. vue 封装dialog_element-ui 封装dialog组件
  7. 服务器物理内存高,服务器的物理内存高
  8. cryptojs aes加密每次结果不同_Javascript加密算法标准库,支持Nodejs+浏览器——crypto-js...
  9. Java设计模式(装饰者模式-组合模式-外观模式-享元模式)
  10. 用于检测AC电压的无接触电压检测器