-
Notifications
You must be signed in to change notification settings - Fork 21
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Futures in Scala 2.12: Part 8 — sun.misc.Unsafe
- Loading branch information
1 parent
76c13db
commit 1c79d46
Showing
1 changed file
with
46 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
#Futures in Scala 2.12 (part 8) | ||
|
||
This is the eighth of several posts describing the evolution of `scala.concurrent.Future` in Scala `2.12.x`. | ||
For the previous post, [click here](https://github.com/viktorklang/blog/blob/master/Futures-in-Scala-2.12-part-7.md). | ||
|
||
##Goodbye, sun.misc.Unsafe | ||
|
||
A `Future` can be seen as a tri-state<sup>[1](#tristate)</sup> state machine with the following distinct states: | ||
|
||
1. Uncompleted | ||
2. Completed with a successful result | ||
3. Completed with a failed result | ||
|
||
In order to have an «asynchronous Future» it is vital to be able to register logic to be executed once the `Future` becomes Completed. | ||
|
||
This means that we can encode the state `1` as a «sequence of callbacks & their `ExeutionContext`», state `2` as a `scala.util.Success`, and state `3` as a `scala.util.Failure`. | ||
|
||
Given that, we only need to have a single `var` in our `Future`-implementation, which will either be a `Seq`, a `Success` or a `Failure`. | ||
|
||
Since `Future` can both be completed and have new callbacks added *concurrently* we need to be able to access this `var` atomically, so simply making it `@volatile` won't be enough: we need *Compare-And-Set* semantics. | ||
|
||
In the original `scala.concurrent.Future` design, we used what's known as an [`AtomicReferenceFieldUpdater`](https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/atomic/AtomicReferenceFieldUpdater.html) (ARFU). | ||
|
||
Now, from a Scala perspective there are 2 problems with ARFUs: 1. They require the use of static fields—which Scala does not support, and, 2. They are about 10-20% slower than `sun.misc.Unsafe` access. | ||
|
||
Since performance is always important in the Standard Library, we opted to use `sun.misc.Unsafe` and be OK with it requiring us to have a base-class in Java with a static field to hold the memory address offset of the field. | ||
|
||
But! For 2.12.x we decided to take a better way, which eliminates the need for static fields and `sun.misc.Unsafe: | ||
|
||
We have now *completely replaced* the use of `sun.misc.Unsafe` for `DefaultPromise` (the internal implementation of the Scala Standard Library Promises) with [`AtomicReference`](https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/atomic/AtomicReference.html). | ||
|
||
###Benefits | ||
|
||
1. The same, excellent, performance as previously | ||
2. With much better platform compatibility and security | ||
|
||
<a name="tristate">1</a>: In practice it turns out to be a four-state state machine due to the feature of «Promise Linking», we'll cover that topic in the next post. | ||
|
||
[Here's the RSS feed of this blog](https://github.com/viktorklang/blog/commits/master.atom) and—as I love feedback—please [share your thoughts](https://github.com/viktorklang/blog/issues/3). | ||
|
||
To comment on the blog post itself, [click here](https://github.com/viktorklang/blog/pull/11/files). | ||
|
||
Stay tuned for many more updates about Futures in Scala 2.12! | ||
|
||
Cheers, | ||
√ |