title: If an object is not mutated anymore, can it be safely shared across threads? (Scala/Java)
body: <p>If an object is not mutated anymore, can it be safely shared across threads? Or in other words: are var (non-final) fields safely published if they are practically immutable?</p>
  
  <p>A contrived example with pseudo (sorry) code:</p>
  
  <pre><code>class Root {
    var field1: Int = 0
    var field2: String = ""
    var field3: SomeOtherObject = null
    // many more fields here
  }
  
  class SomeOtherObject {
    var field1: String = ""
    var field2: YetAnotherObject = null
  }
  
  var root = new Root()
  root.field1 = 123
  root.field2 = "some string"
  root.field3 = new SomeOtherObject()
  root.field3.field1 = "data"
  root.field3.field2 = new YetAnotherObject()
  
  // ... So basically an object tree of arbitrary levels of nesting
  
  // From here on out none of the fields will change
  
  // now if other threads use the above data, e.g.
  
  Future {
    println(root.field1)
  }
  
  new Thread() {
    override def run() = root.field3.field1 ++ "hello"
  }.start()
  
  // In the real project it will be a thread from a webserver getting passed the object tree root
  </code></pre>
  
  <p>I realise this is not very idiomatic Scala. Let's imagine I don't actually have access to the code creating the object tree. </p>
  
  <p>As far as I know this code is not thread safe. None of the data is safely published. None of the fields are final (val) and there's no synchronisation primitive in sight (besides <code>Thread.start()</code> and whatever is inside <code>Future.apply</code>.</p>
  
  <p>I'm not asking how to make it thread-safe. My question is: is it thread-safe to share mutable data if it won't ever change after passing the reference through which that data can be reached is shared? I don't believe the JMM/jsr133 guarantees this for non-final fields. </p>
  
  <p><strong>However</strong> I cannot make a test program that proves this code is broken and needs more synchronisation. Leading me to believe something in the JMM after Java5 added a stronger guarantee? I'm using Scala 2.12 on Java8.</p>
  
  <p>I've found this <a href="https://shipilev.net/blog/2014/all-fields-are-final/" rel="nofollow noreferrer">all fields are final</a> as well as <a href="https://openjdk.java.net/jeps/188" rel="nofollow noreferrer">jep188</a>, but those are only proposals. Can anyone point me to the rule/specification why above code seems to be safe?</p>