8 Great Java 8 Features No One's Talking about--转载
原文地址:http://www.infoq.com/articles/Java-8-Quiet-Features
If you haven’t seen some of the videos or tutorials around Java 8, you’ve probably been super-busy or have a more interesting social life than I do (which isn’t saying much). With new features like lambda expressions and Project Nashorn taking so much of the spotlight, I wanted to focus on some new APIs that have been a bit under the radar, but make Java 8 better in so many ways.
1. Stamped Locks
Multi-threaded code has long been the bane of server developers (just ask Oracle Java Language Architect and concurrency guruBrian Goetz). Over time complex idioms were added to the core Java libraries to help minimize thread waits when accessing shared resources. One of these is the classic ReadWriteLock that lets you divide code into sections that need to be mutually exclusive (writers), and sections that don’t (readers).
On paper this sounds great. The problem is that the ReadWriteLock can be super slow (up to 10x), which kind of defeats its purpose. Java 8 introduces a new ReadWrite lock – calledStampedLock. The good news here is that this guy is seriously fast. The bad news is that it’s more complicated to use and lugs around more state. It’s also not reentrant, which means a thread can have the dubious pleasure of deadlocking against itself.
StampedLock has an "optimistic" mode that issues a stamp that is returned by each locking operation to serve as a sort of admission ticket; each unlock operation needs to be passed its correlating stamp. Any thread that happens to acquire a write lock while a reader was holding an optimistic lock, will cause the optimistic unlock to be invalidated (the stamp is no longer valid). At that point the application can start all over, perhaps with a pessimistic lock (also implemented in StampedLock.) Managing that is up to you, and one stamp cannot be used to unlock another – so be super careful.
Let’s see this lock in action-
long stamp = lock.tryOptimisticRead(); // non blocking path - super fast
work(); // we're hoping no writing will go on in the meanwhile
if (lock.validate(stamp)){
//success! no contention with a writer thread
}
else {
//another thread must have acquired a write lock in the meanwhile, changing the stamp.
//bummer - let's downgrade to a heavier read lock stamp = lock.readLock(); //this is a traditional blocking read lock
try {
//no writing happening now
work(); }
finally {
lock.unlock(stamp); // release using the correlating stamp
}
}
2. Concurrent Adders
Another beautiful addition to Java 8, meant specifically for code running at scale, is the concurrent “Adders”. One of the most basic concurrency patterns is reading and writing the value of a numeric counter. As such, there are many ways in which you can do this today, but none so efficient or elegant as what Java 8 has to offer.
Up until now this was done using Atomics, which used a direct CPU compare and swap (CAS) instruction (via the sun.misc.Unsafe class) to try and set the value of a counter. The problem was that when a CAS failed due to contention, the AtomicInteger would spin, continually retrying the CAS in an infinite loop until it succeeded. At high levels of contention this could prove to be pretty slow.
Enter Java 8’sLongAdders. This set of classes provides a convenient way to concurrently read and write numeric values at scale. Usage is super simple. Just instantiate a new LongAdder and use itsadd() andintValue() methods to increase and sample the counter.
The difference between this and the old Atomics is that here, when a CAS fails due to contention, instead of spinning the CPU, the Adder will store the delta in an internal cell object allocated for that thread. It will then add this value along with any other pending cells to the result of intValue(). This reduces the need to go back and CAS or block other threads.
If you’re asking yourself when should I prefer to use concurrent Adders over Atomics to manage counters? The simple answer is – always.
3. Parallel Sorting
Just as concurrent Adders speed up counting, Java 8 delivers a concise way to speed up sorting. The recipe is pretty simple. Instead of -
Array.sort(myArray);
You can now use –
Arrays.parallelSort(myArray);
This will automatically break up the target collection into several parts, which will be sorted independently across a number of cores and then grouped back together. The only caveat here is that when called in highly multi-threaded environments, such as a busy web container, the benefits of this approach will begin to diminish (by more than 90%) due to the cost of increased CPU context switches.
4. Switching to the new Date API
Java 8 introduces a complete new date-time API. You kind of know it’s about time when most of the methods of the current one are marked as deprecated... The new API brings ease-of-use and accuracy long provided by the popular Joda time API into the core Java library.
As with any new API the good news is that it’s more elegant and functional. Unfortunately there are still vast amounts of code out there using the old API, and that won’t change any time soon.
To help bridge the gap between the old and new API’s, the venerable Date class now has a new method calledtoInstant() which converts the Date into the new representation. This can be especially effective in those cases where you're working on an API that expects the classic form, but would like to enjoy everything the new API has to offer.
5. Controlling OS Processes
Launching an OS process from within your code is right there with JNI calls – it’s something you do half-knowing there’s a good chance you’re going to get some unexpected results and some really bad exceptions down the line.
Even so, it’s a necessary evil. But processes have another nasty angle to them - they have a tendency to dangle. The problem with launching process from within Java code so far has been that is was hard to control a process once it was launched.
To help us with this Java 8 introduces three new methods in the Process class -
- destroyForcibly - terminates a process with a much higher degree of success than before.
- isAlive tells if a process launched by your code is still alive.
- A new overload for waitFor() lets you specify the amount of time you want to wait for the process to finish. This returns whether the process exited successfully or timed-out in which case you might terminate it.
Two good use-cases for these new methods are -
- If the process did not finish in time, terminate and move forward:
if (process.wait(MY_TIMEOUT, TimeUnit.MILLISECONDS)){
//success! }
else {
process.destroyForcibly();
}
- Make sure that before your code is done, you're not leaving any processes behind. Dangling processes can slowly but surely deplete your OS.
for (Process p : processes) {
if (p.isAlive()) {
p.destroyForcibly();
}
}
6. Exact Numeric Operations
Numeric overflows can cause some of the nastiest bugs due to their implicit nature. This is especially true in systems where int values (such as counters) grow over time. In those cases things that work well in staging, and even during long periods in production, can start breaking in the weirdest of ways, when operations begin to overflow and produce completely unexpected values.
To help with this Java 8 has added severalnew “exact” methods to the Math class geared towards protecting sensitive code from implicit overflows, by throwing an unchecked ArithmeticException when the value of an operation overflows its precision.
int safeC = Math.multiplyExact(bigA, bigB); // will throw ArithmeticException if result exceeds +-2^31
The only downside is that it’s up to you to find those places in your code where overflows can happen. Not an automagical solution by any stretch, but I guess it’s better than nothing.
7. Secure Random Generation
Java has been under fire for several years for having security holes. Justified or not, alot of work has been done to fortify the JVM and frameworks from possible attacks. Random numbers with a low-level of entropy make systems that use random number generators to create encryption keys or hash sensitive information more susceptible to hacking.
So far selection of the Random Number Generation algorithms has been left to the developer. The problem is that where implementations depend on specific hardware / OS / JVM, the desired algorithm may not be available. In such cases applications have a tendency to default to weaker generators, which can put them at greater risk of attack.
Java 8 has added a new method calledSecureRandom.getInstanceStrong() whose aim is to have the JVM choose a secure provider for you. If you’re writing code without complete control of the OS / hardware / JVM on which it would run (which is very common when deploying to the cloud or PaaS), my suggestion is to give this approach some serious consideration.
8. Optional References
NulPointers are like stubbing your toes - you’ve been doing it since you could stand up, and no matter how smart you are today - chances are you still do. To help with this age-old problem Java 8 is introducing a new template called Optional<T>.
Borrowing from Scala and Haskell, this template is meant to explicitly state when a reference passed to or returned by a function can be null. This is meant to reduce the guessing game of whether a reference can be null, through over-reliance on documentation which may be out-of-date, or reading code which may change over time.
Optional<User> tryFindUser(int userID) {
or -
void processUser(User user, Optional<Cart> shoppingCart) {
The Optional template has a set of functions that make sampling it more convenient, such asisPresent()to check if an non-null value is available, or ifPresent() to which you can pass a Lambda function that will be executed if isPresent is true. The downside is that much like with Java 8’s new date-time APIs, it will take time and work till this pattern takes hold and is absorbed into the libraries we use and design everyday.
New Lambda syntax for printing an optional value -
value.ifPresent(System.out::print);
About the Author
Tal Weiss is the CEO of Takipi. Tal has been designing scalable, real-time Java and C++ applications for the past 15 years. He still enjoys analyzing a good bug though, and instrumenting Java code. In his free time Tal plays Jazz drums.
8 Great Java 8 Features No One's Talking about--转载的更多相关文章
- Java 8 Features – The ULTIMATE Guide--reference
Now, it is time to gather all the major Java 8 features under one reference post for your reading pl ...
- Java并发编程:Timer和TimerTask(转载)
Java并发编程:Timer和TimerTask(转载) 下面内容转载自: http://blog.csdn.net/xieyuooo/article/details/8607220 其实就Timer ...
- Java并发编程:深入剖析ThreadLocal(转载)
Java并发编程:深入剖析ThreadLocal(转载) 原文链接:Java并发编程:深入剖析ThreadLocal 想必很多朋友对ThreadLocal并不陌生,今天我们就来一起探讨下ThreadL ...
- Java 反射 设计模式 动态代理机制详解 [ 转载 ]
Java 反射 设计模式 动态代理机制详解 [ 转载 ] @author 亦山 原文链接:http://blog.csdn.net/luanlouis/article/details/24589193 ...
- Java并发编程之三:volatile关键字解析 转载
目录: <Java并发编程之三:volatile关键字解析 转载> <Synchronized之一:基本使用> volatile这个关键字可能很多朋友都听说过,或许也都用过 ...
- [Android Tips] 22. Available Java 7 Features in Android
This only allows Java 7 language features, and you can hardly benefit from anything since a half of ...
- JAVA多线程和并发基础面试问答(转载)
JAVA多线程和并发基础面试问答 原文链接:http://ifeve.com/java-multi-threading-concurrency-interview-questions-with-ans ...
- java.lang.ClassNotFoundException: Didn't find class "*****(转载)
很多人出现了java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{*****Activity}: java. ...
- java.lang.OutOfMemoryError: PermGen space及其解决方法(转载)
java.lang.OutOfMemoryError: PermGen space及其解决方法 分类: java2007-09-11 12:34 162242人阅读 评论(51) 收藏 举报 gene ...
随机推荐
- Spring 容器(一)
Source null instanceof Object 语法是正确的 Source定义得到输入流的方法 Resource继承Source,定义判断流是否存在.是否打开等方法 BaseResourc ...
- codeforces 710E Generate a String(简单dp)
传送门:http://codeforces.com/problemset/problem/710/E 分析: 让你写一个全由"a"组成的长为n的串,告诉你两种操作,第一种:插入一个 ...
- 随机模拟的基本思想和常用采样方法(sampling)
转自:http://blog.csdn.net/xianlingmao/article/details/7768833 引入 我们会遇到很多问题无法用分析的方法来求得精确解,例如由于式子特别,真的解不 ...
- LRJ入门经典-0903切蛋糕305
原题 LRJ入门经典-0903切蛋糕305 难度级别:B: 运行时间限制:1000ms: 运行空间限制:256000KB: 代码长度限制:2000000B 试题描述 如图所示有一个矩形蛋糕,上面划分成 ...
- Starting nagios:This account is currently not available.
解决方式: 又一次安装php 再重新启动apache 再启动nagios 再訪问:http://ip/nagios 我的问题就是 解决的.
- 构建基于Javascript的移动CMS——加入滑动
在和几个有兴趣做移动CMS的小伙伴讨论了一番之后,我们认为当前比較重要的便是统一一下RESTful API.然而近期持续断网中,又遭遇了一次停电,暂停了对API的思考.在周末无聊的时光了看了<人 ...
- hdu 5312 Sequence(数学推导——三角形数)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5312 Sequence Time Limit: 2000/2000 MS (Java/Others) ...
- SPSS提示“列表中不同意存在字符串变量”的解决方法
今天用SPSS对一些数据进行主成分分析,SPSS 19.0进行主成分分析的方法是:分析--降维--因子分析,可是当导入一些变量的时候.就会弹出窗体说"列表中不同意存在字符串变量", ...
- IOS的四种数据存储方式及优劣
IOS有四种经常使用数据存储方式: 第一种方法:用NSUserDefaults存储配置信息 NSUserDefaults被设计用来存储设备和应用的配置信息.它通过一个工厂方法返回默认的.也是最经常使用 ...
- 指尖上的电商---(10)SolrAdmin中加入多核
在Solr中有的时候,我们并不仅仅是须要一种形式的索引文件.可能须要多种不同数据的索引文件.这时我们就能够在同一个Solr以下创建 多核. 比方,我们在solr以下想把产品信息和分类信息各存放一个索引 ...