2

I'm reading the netty source code, and come across a synchronized on formal parameter.

AbstractBootstrap(AbstractBootstrap<B, C> bootstrap) {
    localAddress = bootstrap.localAddress;
    synchronized (bootstrap.options) {
        options.putAll(bootstrap.options);
    }
}

localAddress is not synchronized because it's declared as volatile, any change to it is visable to other thread.

But I don't understand to synchronized on a formal parameter bootstrap.

bootstrap is a formal parameter, every thread has it's own copy. synchronized on it only effect it's own thread? Is this opinion correct?

synchronized (bootstrap.options) is to prevent bootstrap.options to be modified outsides this class or to prevent this.options to be modified by other thread?

NingLee
  • 1,477
  • 2
  • 17
  • 26

3 Answers3

2

bootstrap is a formal parameter, every thread has it's own copy. synchronized on it only effect it's own thread? Is this opinion correct?

No, this is not strictly correct. The parameter bootstrap contains a reference to an object, it is not a local copy of the object. Therefore other threads could have their own references to the same instance of the object.

synchronized (bootstrap.options) is to prevent bootstrap.options to be modified outsides this class or to prevent this.options to be modified by other thread?

Kinda. It will block until the current thread can acquire exclusive access to the the object that is in bootstrap.options. It appears to be doing this because bootstrap.options is some kind of collection that is not itself thread safe, and so it is protecting the behaviour of the map under concurrent usage.

Chris K
  • 11,622
  • 1
  • 36
  • 49
  • The `synchronized` parameter `bootstrap.options` is only a reference to an instance, if the instance itself is changed outside, the reference is changed too. So the `synchronized` prevent any other threads to change the instance. Is it right? – NingLee Oct 20 '15 at 11:09
  • @NingLee there are two fields called options, which does not help. bootstrap.options is having all of its contents copied and placed into another field called options. The synchronized keyword locks bootstrap.options, but it does not lock options. That said options looks to be part of the object under construction, and so that is implicitly thread safe at that time and so does not need protecting. It is bootstrap.options that that code is locking from external interference. – Chris K Oct 20 '15 at 11:13
  • ok, I see. I does means the `bootstrap.options` not the `options`. If an object is `synchronized`, any other thread can't modify it until the `synchronized` block is finished. – NingLee Oct 20 '15 at 11:27
  • @NingLee very nearly. it means that any other thread who ALSO calls synchronized will not be able to. But if there is another thread that tries, and they do not call synchronized then there will be a bug there. Both sides must call synchronized in order for it to fully work. – Chris K Oct 20 '15 at 11:44
  • @NingLee, To clarify what Chris K said, synchronizing on an object does _not_ prevent other threads from accessing or modifying the object. It only prevents other threads from synchronizing on the same object at the same time. – Solomon Slow Oct 20 '15 at 13:29
  • @jameslarge ok, I see. Only with `synchronized`, JVM will try to get the lock, without `synchronized` JVM will directly access the object even the object is `synchronized` anywhere else. – NingLee Oct 21 '15 at 02:11
  • @NingLee, Yes, only I just want to make sure you understand that there is no connection between `synchronized` and accessing an object. Accessing an object inside a synchronized block is no different from accessing it anywhere else. If you want to protect an object from access by multiple threads, then it's up to _you_ to make sure that your code only accesses it from inside blocks that are all synchronized on the same lock. – Solomon Slow Oct 21 '15 at 13:00
  • Exactly. An objects monitor is done by convention, it is not automatically checked for us and enforced by the language. A good tutorial that covers this can be found at https://docs.oracle.com/javase/tutorial/essential/concurrency/sync.html, and the book Java Concurrency in Practice is excellent. – Chris K Oct 21 '15 at 13:04
0

Every constructor invocation receives a copy of the reference variable pointing to an AbstractBootstrap instance.

If you reference another instance within the constructor, the change will only affect the copy that constructor received. But any change in the AbstractBootstrap instance will be reflected to all the threads sharing it.

Hope it helps,

Esteban Aliverti
  • 6,259
  • 2
  • 19
  • 31
0

Most likely, this looks to be the case to lock the bootstrap options (some mutable map) while merging options. As there is no additional source code, what I can infer is that bootstrap instance (which is passed as parameter) and its options field is shared between different threads. That's why the synchronization is required.

Mohit
  • 1,740
  • 1
  • 15
  • 19