Notes From No Fluff Just Stuff November 2011

I attended the No Fluff Just Stuff conference here in Chicago back in November 2011. I took  a few notes on some of the lectures. Here are my notes on some of the lectures on concurrency. I may post in a while with notes from more lectures, as well as some more thoughts on concurrency.

Venkat: concuurrency without pain in pure Java
Why Concurrency?
Java gave us a consistent API for multi-threading
Errors are worse on multi-core machines – multiple levels of cache in application
To get concurrency correct, you have to be God.
That model is the synchronize and suffer model
2 other models: Software Transaction Memory and Actors

public class Account {
    private int balance;
    public Account
}

Synchronized helps you cross the memory barrier synchronizing main and working memory
Locking and race condition is only part of the story
Do not synchronize the accounts, synchronize the transactions
You should also synchronize in the class using the Account classes

synchronized(from) {
    synchronized(to) {
        // do stuff
    }
}

There could be livelock or deadlock
But you could wait a long time.
But you cannot tell synchronized() to timeout.

So instead in Account, use a ReentrantLock
in Account.deposit method, use ReentrantLock.tryLock(long, TimeUnit)

This makes code more complex. synchronized blocks are pretty easy.
Don’t forget to call Reentrant.unlock()
But what if there is an exception before that? Put it in a finally.
This is why we don’t use raw JDBC

Deadlock: I have lock on A, I need a lock on B. You have a lock on B, you need a lock on A.
You could impose an order
If someone introduces a new method, all your locking could be ruined. It’s like a bathroom with a lot of doors. You got to lock every one.
Concurrency on JDK is like a mother-in-law: It’s waiting for you to fail.
95% of Java is broken for concurrency, and we don’t know it yet.

STM: Software Transaction Memory
Everything is immutable (almost everything)
Managed Mutable Identity is also in Clojure
Sharing is good, mutability is good, shared mutability is bad
Separates state from identity
identity points to state
Like stock price: $600 at 1:00 PM, $610 at 1:10
The price at 1PM on November 11, 2011 will always be $600
We can flip a switch to point identity to a new value
Immutability means no locks

the problem is not that it is failing, but that it is misbehaving quietly and you do not know it.
MMI fails loudly if you mess with it outside of a transaction
transaction thread runs in a cone of silence
final change is visible to outside world

If there is a collision, a transaction could repeat
Clojure is written in Java – it’s another JAR, and you can use it in Java

change int in Account to clojure.lang.Ref

private Ref balance
public Account(final int initialBalance) {
    balance = new Ref( initialBalance );
}

int will be replaced with java.lang.Integer
You can only put immutable stuff in there.
Also

public void deposit(final int amount) {
    LockingTransaction.runInTransaction( new Callable< Void >() {
        public Void call() throws Exception() {
        if (amount > 0) { balance.set( getBalance() + amount ) }
        return null;
        }
    });
}
public int getBalance()   { return (Integer) balance.deref(); }

Clojure:

(def balance (ref 0))
(println @balance)
(dosynch (ref-set balance 1) )
(println @balance)

You could still have race conditions. The AccountService that does the transfer still needs a transaction to wrap around the transactions in the Account classes
A transaction in STM could repeat 100,000 times – so do not print, send email

STM: we don’t see any locks (so no deadlocks)
2 drawbacks:
1. STM requires state be immutable – greate for Clojure – the only language where concurrency is safe
2. Code could ge slow or fail due to retries
Hard to be functional in Java
Another option: Isolated mutability – only one thread can touch it at a time
Actors and active objects
An actor can receive many messages at once, but they only work on one at a time
Akka library – now we use Scala’s implementation
Akka gives us STM and Actors

ActorRef ratcliff = Actors.actorOf(HollywoodActor.class).start();
ratcliff.sendOneWay( "Potter" );
ratcliff.stop();

HollywoodActor extends UntypedActor() {
    public void onReceive( final Object message )
}

So we passed a message. We did not call a method directly.
Actors do not hold Threads hostage
Actors could fail
Each Actor is sequential
Could deadlock with 2-way messaging

JDK concurrency APIs are assembly language of concurrency

But can Java web developers do this?

Ted Neward Guava:
Get rid of mutable state

Image from  Codex Amiatinus, a 6th century Vulgate manuscript housed at the Laurentian Library in Florence. Image from Wikimedia. This image is assumed to be allowed under Fair Use.