[FIXED JENKINS-25863] Jenkins tries to build jobs on nodes that are removed

- Any time you have multiple volatiles and you are trying to coordinate state between them, you have failed.
  You either want to have a value object holding the effective state and make that the instance field holding
  that value object volatile, or you probably should just use a lock... because lets face it, the instance field]
  will probably need compare and set semantics any time you want to change the state and your performance
  was shot anyway with the multiple memory barriers for each access of the multiple volatile fields

- In this case we had an "extra" volatile field that could be removed completely, reducing the state that
  requires a lock to just the `workUnit` and `started` fields. We use an internal hidden intrinsic lock
  field in order to reduce the scope of the lock. We also remove the locks on a public object (`Executor`)
  in favour of locking on `stateLock` as those locks were only used to guard access to the (then) volatile
  `started` field (hint: if your field is volatile and you need a lock to access it, you have failed again!)

- In the case of `WorkUnit`, we remove the volatile and replace with the intrinsic lock for all the mutable state
  It might be better to use a lock object, but the scope of this object is such that the intrinsic lock should
  be safe (i.e. we don't want anyone ever locking on a `WorkUnit` explicitly) and we can obtain better performance
  with the intrinsic lock. If the analysis proves incorrect, or if people abuse this and start locking on
  `WorkUnit` we can safely switch to an internal lock object.