But It Works On My Machine…
public class TestVolatile implements Runnable {
private boolean stopRequested = false;
public void run() {
while(!stopRequested) {
// do something here...
}
}
public void stop() {
stopRequested = true;
}
public static void main(String[] args) throws InterruptedException {
TestVolatile tv = new TestVolatile();
new Thread(tv, "Neverending").start();
Thread.sleep(1000);
tv.stop();
}
}
What happens when we run main()?
Of course, the erudite, tech-savvy, good-looking Java people (the type who read my blog), can answer that in a heartbeat.
The answer is that we don’t know for sure when the program will terminate, because the stopRequested variable is not marked volatile. So when we call stop() in the main thread, the Neverending thread may never see that stopRequested has changed to true, and it just keeps going… and going… and going… just like the Energizer Bunny. We never know when it’s gonna stop.
But… it works just fine on my machine
A friend of mine wasn’t convinced though, so just to prove it to him, I typed that in Eclipse and ran it, fully expecting that it would run forever.
It stopped in about one second. Hmmm. Weird.
Seems that the change made from the main thread to stopRequested is immediately visible from the Neverending thread, although stopRequested is not volatile.
Out of curiosity, I modified the program a bit to look like this:
import java.util.concurrent.TimeUnit;
public class TestVolatile implements Runnable {
private boolean stopRequested = false;
private volatile long justAfterStopRequested;
private volatile long afterNeverendingHasStopped;
public void run() {
while(!stopRequested) {
// do something
}
afterNeverendingHasStopped = System.currentTimeMillis();
}
public void stop() {
stopRequested = true;
justAfterStopRequested = System.currentTimeMillis();
}
public static void main(String[] args) throws InterruptedException {
TestVolatile tv = new TestVolatile();
Thread t = new Thread(tv, "Neverending");
t.start();
// let main thread sleep for 1 second before requesting
// Neverending to stop
TimeUnit.SECONDS.sleep(1);
tv.stop();
// wait until Neverending has stopped
t.join();
System.out.println(tv.afterNeverendingHasStopped - tv.justAfterStopRequested);
}
}
I’m trying to see how much time the Neverending thread needs to realize that stopRequested has changed to true, and get outside the loop. The result is 0.
But it can’t be instantaneous–there must be some difference in time. So I changed the System.currentTimeMillis() calls to System.nanoTime(). The result is virtually the same, ranging from around -300 to +300 nanoseconds (we can’t say which one gets modified first, justAfterStopRequested or afterNeverendingHasStopped–it differs on each run). But for all practical purposes, we can say that the Neverending thread sees the change to stopRequested almost immediately.
Strange.
In Effective Java, 2nd ed., Joshua Bloch says in his machine such a program never stops running. Not that I have a self-esteem problem or whatever, but when it comes to Java, if I have to choose whether to trust Joshua Bloch or me, I choose the former. Sorry, me.
On another machine, however…
But you know what? I found that TestVolatile did run forever on Solaris! (Well, it ran until I was back 15 minutes later and killed it anyway.) Is it because of the differences between Windows and Solaris? Not really–it’s more about the differences between the Server VM and the Client VM. My Solaris test platform is a server-class machine, so by default I was using the Server VM. Whereas on my Windows machine by default I was running the Client VM.
Indeed, when I ran the program again on Solaris with the Client VM (with the -client option), it stopped after roughly a second, without having to make stopRequested volatile. Conversely, when I ran the program on Windows with the -server option, it never stopped, and would only stop if I made stopRequested volatile.
This shows that the Client VM may deceive us into thinking that we don’t need volatile (until we run our program on a server-class machine and things start breaking in strange ways). Superficially, the Client VM and the Server VM may sound like they’re not that different. But some differences do matter: what we see here is a real example where the differences between the Client VM and the Server VM can make or break your application.
And that’s not all. There’s another non-obvious thing that may mask the need of volatile in our programs. Like System.out.println(), for example.
Hidden synchronized blocks sometimes hide the need for volatile
If we want to print a counter variable within the loop like this:
public class TestVolatile implements Runnable {
private boolean stopRequested = false;
private int i = 0;
public void run() {
while(!stopRequested) {
System.out.println(i++);
}
}
public void stop() {
stopRequested = true;
}
// the rest
}
Then the program will always terminate even if we don’t mark stopRequested as volatile. Why? Because there is a synchronized block inside System.out.println(). When the thread that runs the run() method calls System.out.println(), its copy of stopRequested gets updated with the latest value, and the while loop terminates.
Note though, that this is NOT guaranteed by the Java Memory Model. The JMM guarantees visibility between two threads that enter and exit synchronized blocks protected by the same lock. If the synchronized blocks are protected by different locks, then the only safe assumption is to assume that there’s no synchronization at all.
This program below does stop,
public class TestVolatile implements Runnable {
private boolean stopRequested = false;
private int i = 0;
private final Object lock1 = new Object();
private final Object lock2 = new Object();
public void run() {
while(!stopRequested) {
synchronized(lock1) {}
i++;
}
}
public void stop() {
stopRequested = true;
synchronized(lock2) {}
}
// the rest
}
even though the two threads are entering synchronized blocks guarded by different locks. We can even remove the synchronized block guarded by lock2 in stop(), and the program still stops. But not the other way around (that is, if we remove lock1’s synchronized block and leave lock2’s there, again the program will run forever).
So it seems that the thread that reads a variable gets the up-to-date value when it executes a synchronized block, regardless of the lock used to guard the block. Even if the variable is not volatile. Which means it’s possible to have code that used to work when you had System.out.println() calls sprinkled throughout suddenly stops working properly when you remove those calls!
Does volatile cascade to member variables? Array elements? Items in collections?
Now let’s say instead of a primitive boolean, stopRequested is a member variable of another class, like this:
import java.util.concurrent.TimeUnit;
public class TestVolatile implements Runnable {
private A wrapper = new A();
public void run() {
while(!wrapper.stopRequested) {
// do something
}
}
public void stop() {
wrapper.stopRequested = true;
}
public static void main(String[] args) throws InterruptedException {
TestVolatile tv = new TestVolatile();
new Thread(tv, "Neverending").start();
// let main thread sleep for 1 second before requesting
// Neverending to stop
TimeUnit.SECONDS.sleep(1);
tv.stop();
}
}
class A {
boolean stopRequested = false;
}
Run with the -server flag, this one never stops either. But what if we mark wrapper as volatile:
private volatile A wrapper = new A();
Does the “volatility” of the reference cascades to the member variable stopRequested as well? Turned out, looks like the answer is yes. We can either mark wrapper as volatile, or stopRequested as volatile, and the program will terminate in about a second.
I’m not surprised that the program terminates when I mark stopRequested as volatile. But why wrapper as volatile works as well? The same thing happens when we use an ArrayList, like this:
import java.util.ArrayList;
import java.util.List;
public class TestVolatile implements Runnable {
List<Boolean> wrapper = new ArrayList<Boolean>();
public TestVolatile() {
wrapper.add(Boolean.FALSE);
}
public void run() {
while(wrapper.get(0) == Boolean.FALSE) {
// do something
}
}
public void stop() {
wrapper.set(0, Boolean.TRUE);
}
// the rest of the code...
}
Run as it is, it never stops. If we mark the List<Boolean> wrapper as volatile, it stops pretty fast.
I wonder why? The object reference to that List instance itself never changes. We’re only changing an element within the List, and not the List itself. There’s no hidden synchronized block. Why does the Neverending thread sees the up-to-date value of stopRequested?
Above and beyond the call of duty
Before JSR 133, if thread A writes to volatile field f, thread B is guaranteed to see the new value of f only. Nothing else is guaranteed. With JSR 133 though, volatile is closer to synchronization than it was. Reading/writing a volatile field now is like acquiring/releasing a monitor in terms of visibility. As the excellent FAQ says: “… anything that was visible to thread A when it writes to volatile field f becomes visible to thread B when it reads f.”
But still, all these new guarantees for volatile doesn’t answer the question:
public class TestVolatile implements Runnable {
private volatile A wrapper = new A();
public void run() {
while(!wrapper.stopRequested) {
// do something
}
}
public void stop() {
wrapper.stopRequested = true;
}
// the rest
}
Why does this work? In stop() we’re not exactly writing to wrapper. We’re just using it to change the value of stopRequested. So why does the other thread see the change?
Unfortunately, in the examples I’ve seen so far in books and countless articles, a volatile field is always a primitive, so it’s kinda hard to find the answer to my question. So I did the only remaining way I know to proceed: asking The Concurrency Expert himself. And I was pleasantly surprised to find that he replied very quickly! Here’s what Brian Goetz said:
The Java Memory Model sets the minimum requirements for visibility, but all VMs and CPUs generally provide more visibility than the minimum. There’s a difference between “what do I observe on machine XYZ in casual use” and “what is guaranteed.”
So there. The VM in this case just goes above and beyond what it is supposed to do. But there’s no guarantee that on another VM and another CPU, the same thing will happen.
Conclusion
So here’s what I’ve learned from this little experiment:
- If your application is a server application, or will run on a server-class machine, remember to use the -server flag during development and testing as well to uncover potential problems as early as possible. The Server VM performs some optimizations that can expose bugs that do not manifest on the Client VM.
- Just because it works on your machine, doesn’t mean that it’ll work on other machines running other VMs too. It’s important to know what are exactly guaranteed, and code with those minimal guarantees in mind, instead of assuming that other VMs and OSes will be as forgiving as the ones you’re using for development.
- (This is closely related to #2 above.) Because VMs and CPUs generally provide more visibility than the minimum guaranteed by JSR 133, it’s good to know the extra things that they do that may mask a potential bug. For example, at least in some VMs, calling
System.out.println()forces the change to a non-volatile variable to be visible to other threads because it has a synchronized block inside. This can explain a bug that appears after you’ve made a seemingly unrelated change (that removes a synchronized block from the execution path, for instance).
Whenever I Think Something Is Too Tough For Me…
I think of Chris Gardner in his Pursuit of Happyness. Because nothing, absolutely none of the WORST things I’ve ever experienced in my entire life is even within an AU of the things that this amazing man had to go through. And if you think that what you saw in the movie version (starring Will Smith) was bad… the actual, real-life version was WORSE. In the movie he had to stay in jail for one night. In real life he had to stay for ten. For parking tickets!
From now on, whenever I see somebody is being nasty, sullen, or angry, I’m going to be more understanding. I never know what’s really happening in his or her life.
From now on, whenever I think I’m having it tough, I know that no matter what that is, it is not worse than something that Chris Gardner has gone through. And if Chris Gardner can rise above his industrial-strength, high-grade, class A problems, heck, I can rise above my small-scale, low-grade, class-C problems and smash them to bits.
From now on, I will always keep in mind that no matter how low, dejected, miserable a person may seem to be now, I may be looking at Greatness in the eye. It’s a reminder of how everyone has the potential to greatness within them.
Are You Making Enough Money? (And Why “The Millionaire Next Door” Sucks)
I love benchmarks. I love the fact that I can always see how I am doing compared to other people, and the fact that I can measure my progress–it’s a bit like the joy of leveling up in games. Maybe it’s a guy thing. Here are the salary benchmarks that I found, created by the good people behind salary.sg site.
There are 3 benchmarks that I like:
- Compare your income against all Singapore resident taxpayers. This one tells you how well you’re doing compared to other taxpayers in Singapore. For instance, if you’re making 100k/year, you are at the 83.1th percentile. Which should either make you feel good, or, if you’re like me, make you think that that means you’re at the bottom of the top 20%. Ha! (They also have a “feel good” version, which includes the non tax-paying residents as well here, but I think it’s rather pointless. If you are in the taxable group, why do you need to make yourself feel better by comparing yourself against those in the non-taxable group? It’s like you’re a slow runner, and instead of working out and finding out how to run faster, you make yourself feel better by the fact that a guy who doesn’t have legs can’t run faster than you.)
- Benchmark your income by age group. Ooooh, I love this one. I mean after all, if you don’t compare so well in the benchmark above, that may be because there are a lot of people in their forties make a lot more than you do, right? But this benchmark also serves a very important purpose: to track your progress as you grow older. For instance, if a girl makes 6k/month and she’s only 28, then she’s at the 98th percentile. That’s pretty damn good! But say she stays in the same company for 10 years, getting a 3% raise every year. By the 10th year, she’s making around $8000 per month. Is she still doing well? Not as much, because that drops her into the 90.9th percentile only, not considering inflation etc. She has to do something more to keep her at her original percentile. I absolutely love this benchmark.
- Income + net worth benchmark for those over 30. I love this one too! It’s good to know that if I want to be at the top 10%, I have to earn at least $147k. Like the article says, so different from the school days eh? It’s also a humbling and enlightening experience to see that I’m not a wealth accumulator, and what I should shoot for if I want to be a wealth accumulator. Taken from the site: “According to the book The Millionaire Next Door if your net worth equals (or exceeds) your age times your annual income divided by 10, then you are a “wealth accumulator”.” Damn. I’m not a wealth accumulator. From now on I aim to be one.
Now, don’t get me wrong. I hate that book. I think Millionaire Next Door is a horrible, boring, misguided book. You do NOT build wealth by penny-pinching! You can save 90% of your salary every month, but if you make $1000 per month, I’m sorry, you will NOT be a millionaire, mister. Well, you will, actually, after 56 years of living as a tightwad penny-pincher, assuming 8% annual return. Then, of course, you die! (Makes you feel good that you spend $50 on that excellent meal, eh? At least you probably die happier than that poor tightwad.)
My point is that this book is so misguided because it concentrates too much on penny-pinching, so much so that most people with the potential to become rich will just give up because they portray the millionaire journey to be an extremely boring, dull, and painful one. They didn’t realize that there is another side that is a lot more interesting and exciting: how to multiply and/or increase your income radically, which involves a lot more interesting things such as striving to be the best you can be, networking with interesting people, intelligent career choice, wise and prudent investing, asset and wealth protection… and of course, REWARDING YOURSELF ONCE IN A WHILE FOR ALL THAT EFFORT. The two Ph.D. authors just missed these whole bunch of other things completely, and wasted hundreds of pages concentrating on pain, pain, pain, pain, pain. Well done, guys!
And I thought I was talking about benchmarks
But I saw the opportunity to finally say what I’ve always wanted to say about that horrible book Millionaire Next Door and I couldn’t help myself. Sorry. But yes, I love those 3 benchmarks a lot. It’s a constant reminder to me that there are always people earning a lot more than I do, and that I can learn from them to see how they do it. How exciting!
When A Synchronized Class Isn’t Threadsafe
Every Java programmer has heard this advice before: “Prefer ArrayList over Vector. Vector is fully synchronized, and as such you’re paying the synchronization penalty even when you don’t need it.”
ArrayList is not synchronized, so when you need it you need to perform synchronization yourself, or alternatively, as the ArrayList javadoc entry says: “… the list should be “wrapped” using the Collections.synchronizedList method.” Something like this:
List list = Collections.synchronizedList(new ArrayList());
The resulting List will be synchronized, and therefore can be considered safe.
Or is it?
Not really. Consider the very contrived example below.
final List<String> list = Collections.synchronizedList(new ArrayList<String>());
final int nThreads = 1;
ExecutorService es = Executors.newFixedThreadPool(nThreads);
for (int i = 0; i < nThreads; i++) {
es.execute(new Runnable() {
public void run() {
while(true) {
try {
list.clear();
list.add("888");
list.remove(0);
} catch(IndexOutOfBoundsException ioobe) {
ioobe.printStackTrace();
}
}
}
});
}
As long nThreads is 1, everything runs just fine. However, increase the number of nThreads to 2, and you start getting this:
java.lang.IndexOutOfBoundsException: Index: 0, Size: 0
at java.util.ArrayList.RangeCheck(Unknown Source)
at java.util.ArrayList.remove(Unknown Source)
at java.util.Collections$SynchronizedList.remove(Unknown Source)
Changing the synchronized List to Vector doesn't help either. What happened here? Well, individual method calls of synchronized List and Vector are synchronized. But list.add() and list.remove() can be called in any order between the 2 threads. So if you print list.size() after list.add(), the output is not always 1. Sometimes it's 0, sometimes it's 2. Likewise, thread 1 may call list.add(), but before it gets a chance to call list.remove(), thread 2 gets into action and calls list.clear(). Boom, you get IndexOutOfBoundsException.
In that example above, the 3 calls to List's methods have to be atomic. They must happen together as one unit, no interference from other threads, or else we'll get the IndexOutOfBoundsException again. The fact that the individual methods are synchronized is irrelevant. In fact, we can go back to using the non-synchronized ArrayList, and the program will work, as long as we synchronize properly to make the 3 calls happen as one atomic, indivisible unit of execution:
synchronized (list) {
list.clear();
list.add("888");
list.remove(0);
}
The moral of the story is that just because a class is fully synchronized, doesn't mean it's threadsafe (UPDATE: as in doesn't mean your code will be threadsafe from using it--thanks Alex). You still have to be on the look for those sequence of method calls that have to occur atomically, because method level synchronization won't help in this regard. In other words, watch what you're doing. (And yes, we should still prefer ArrayList over Vector.)
Threadsafe Iteration & ConcurrentModificationException
Sometimes it's not so obvious when exactly we're supposed to synchronize our use of Collections. Ever encountered a ConcurrentModificationException before? I bet it's probably because your code looks something like this (a.k.a.: why the for-each loop isn't such a great idea actually):
final List<String> list = new ArrayList<String>();
list.add("Test1");
list.add("Test2");
list.add("Test3");
for(String s : list) {
if(s.equals("Test1")) {
list.remove(s);
}
}
ConcurrentModificationException will be thrown in this case, even when there's only a single thread running. To fix this problem, we can't use the for-each loop since we have to use the remove() method of the iterator, which is not accessible within the for-each loop. Instead we have to do this:
for(Iterator<String> iter = list.iterator(); iter.hasNext();) {
String s = iter.next();
if(s.equals("Test1")) {
iter.remove();
}
}
The point is that iteration is something that we'd probably want to happen atomically--that is, while we're iterating over a collection, we don't want other threads to be modifying that collection. If it happens most probably something is wrong with our design.
This is why if you look into the JDK source code, the implementation for Iterator usually checks the expected modification count (i.e.: how many times is this collection supposed to have been modified?) against the collection's current modification count (how many times this collection has been modified). If they don't tally, the Iterator assumes that another thread has modified the collection while the iteration is going on, so it throws the ConcurrentModificationException. (This is exactly what happens in our single-threaded case about too by the way--the call list.remove() increases the modification count such that it no longer tallies with the one that the iterator holds (whereas iter.remove() resets the mod count so they still tally.) ConcurrentModificationException is a useful exception--it informs us of a probable fault in our design.
When Volatile Fails
However, ConcurrentModificationException is not 100% reliable. The implementation of Iterator.next() may look something like this:
public E next() {
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
// other stuff
That is, ConcurrentModificationException is supposed to be thrown when the mod counts don't tally. But it may not get thrown because the thread on which the modCount check is running is seeing a stale value of modCount. That is, let's say you have thread A iterating through a collection. Whenever you call iter.next(), it checks that modCount == expectedModCount. But modCount may have been modified by thread B, and yet A is still seeing the unmodified value. If you remember, this is what the volatile keyword is about--it is to guarantee that a thread will always see the most recent value of a variable marked as such.
So why didn't Joshua Bloch (or whoever took his place in Sun to take care of the Collections API) mark the modCount volatile? That would at least make the concurrent modification detection mechanism more reliable, yes? Well... no. Actually marking modCount volatile won't help, because although volatile guarantees uptodateness, it doesn't guarantee atomicity.
What does that mean? Well, if you examine the implementation of ArrayList, you'll see that methods that modify the list increment the modCount (non-volatile) variable by one (i.e.: modCount++). So theoretically, if we mark modCount as volatile, whenever thread B says modCount++, thread A should always immediately see the value and throws ConcurrentModificationException.
But there is a problem: the increment operator (++) is not atomic. It is actually a compound read-modify-write sequence. So while thread B is in the middle of executing modCount++, it's entirely possible that the thread scheduler will kick thread B out and decide to run thread A, which then checks for modCount before B has a chance to write back the new value of modCount.
Hidden Iteration
As if things aren't hairy enough as they are, it's not always obvious when an iteration over a collection is happening. Sure, it's probably pretty easy to spot iteration code we've written ourselves, so we can synchronize those. However, much less obvious are the iterations that happen within the harmless-looking methods of the Collections API. If you examine the source code of java.util.AbstractCollection class, for example, you'll see that methods like contains(), containsAll(), addAll(), removeAll(), retainAll(), clear()... practically almost all of them trigger an iteration over the collection. Iteration suddenly becomes a LOT harder to spot!
So What Do We Do?
Sounds pretty hopeless, isn't it? Well... nah. A very, very smart CS professor named Doug Lea has figured it out for the rest of us. He came up with concurrent collection classes, which handle the problems listed above for the most common cases. These concurrent collections have been part of the standard Java API in java.util.concurrent package. For most cases, they are drop-in replacement for the corresponding non-threadsafe classes in java.util package, and if you haven't taken a good look at them, it's time that you do!
How To Buy VMWare at Almost Half The Price, Today
(Disclosure: at this moment, I do NOT own any VMWare shares. I just picked it because it’s the most interesting one to watch these days.)
Man oh man! VMWare just keeps skyrocketing! If you had bought VMW only 3 days ago (October 22, 2007), you’d have got a 10% return off your money in just 3 days now. As I’m typing this, VMW shares are traded at $111.25 during the pre-market hours… and keeps rising. Boom it goes up to $111.26 just as I finished typing the previous sentence!
All of this is very exciting. But they’re all paying too much.
No, I’m not going to point out that the stock is wayyy overpriced like gazillion others have like all the others out there have. I believe that although fundamental analysis is valid, one should ride a trend when the trend is his friend. I’m saying they’re all paying too much because there’s a way of buying VMWare at around $70+ today, and still enjoy the same upward (and downward) movement that VMW has. How? Read on.
You’ve got to LEAP, baby
Say, you’re sure that virtualization is king. You’re convinced that VMWare is the king of this, er, king. Your research has told you that after their glowing Q3 report, the price will probably go up to, say, $130, within say, 3 months. So you want to invest now. NOW! Catch the trend while it’s hot, yadda yadda.
Let’s see. To get one lot of VMW, you need around… wait let me check, $11,150 (excluding commission) now. If it gets up to $130 per share, that’s a profit of around $1,800–around 16%. Quite neat for just 3 months! But what happens if you get it at $72? One lot costs $7,200, and if it gets up to $130 per share, that’s a profit of around $1,800… which is instead of 16% is now a respectable 25% out of the initial investment. Nice!
Here’s how: instead of buying this, buy this instead. The screen capture is shown below.
As you can see, the asking for this KJCAH.X thing is $74.60. Much lower than the real VMW price. But it tracks the VMW movement exactly. What are these things? They are called Long-Term Equity Anticipation Securities, a.k.a.: LEAPS (more info also available here). More specifically, it’s called Deep In The Money call options. Yes, options. The very thing that many investment gurus tell you to stay the heck away from. I suspect that’s because they don’t know options very well themselves.
Basically, for this thing to work, you need to make sure that the following conditions are followed:
- The option’s delta must be as close to 1 (that is, 100%) as possible. When it’s 1, the option price is tracking the stock price almost exactly. That is, if VMW goes up by $10, the option price goes up by $10 as well.
- The expiration date must be as far away as possible in the future. This way you’re less affected by the option decay, and instead you can hold it for longer term, almost like holding the stocks themselves.
In fact as I realized this, I wonder why a lot of people haven’t done this. I discussed this with a bunch of friends and colleagues and although they seem to agree that they see no hole in this scheme, they remain unenthusiastic about it. Which I just can’t understand. You can buy a stock for way less, almost half the price! What more do you want?
Then one friend said, “Well, you test it, and let me know.”
Weird. I guess they’re probably unconvinced because I haven’t made gazillions of dollars using this method. Just like Einstein haven’t shown how to make one twin older than the other by making the other travel near the speed of light… oh wait. People are actually convinced by that one. Oh well. Apparently I’m no Einstein.
If you do see a hole/downside (other than the fact that it has a 3-year expiration, whereas for the shares you can hold it longer, although for the life of me I can’t imagine why anybody would want to keep a stock longer than 3 years if it hasn’t performed as he/she expected), please share it in the comments section!
UPDATE: I think I should clarify more. In that screen capture above, the Strike price for the option is $40. So doesn’t it mean that if I buy the option for $70, I’m buying it at $110 actually (the price of the option + the strike price of the VMW stock)?
Yes, the thing is that I never intend to exercise the option in the first place. What I want to get is the movement of the stock (which is mimicked in lockstep by the option), but not at the price of the stock itself. When the option price moves up because its intrinsic value moves up, I intend to sell it back at a profit. The strike price then is not a factor here.
