Java Concurrency Series Thirteen: security release

1. Definitions

  • Distribution target (the Publish) : make an object can be used by code outside of the current range
  • Object escape (Escape) : a false release. When an object has not yet been constructed, it will be seen by other threads

2. Problem

The right release two objects encountered a problem:

  (1) the reference itself to be seen by other threads;

  State (2) of the object to be seen by other threads.

  ps: In multi-threaded programming, the first and foremost principle is to avoid sharing objects, because if there is no shared objects, so much easier to write multi-threaded, however, if you want to share objects, in addition to the right of the constructor write correctly, but also how to publish a very important issue right.

  

public class Client {
    public Holder holder;
    
    public void initialize(){
        holder = new Holder(42);//这个代码不是原子的
    }
}

public class Holder {
    int n;
    public Holder(int n) {
        this.n = n;
    }
    public void assertSanity() {
        if(n != n)
             throw new AssertionError("This statement is false.");
    }
}

/ ** 
    in Client class, Holder object is released, but this is an incorrect release. Due to visibility problems, other threads can see Holder object in an inconsistent state, even in the constitution of the structure function of the object in the right already built invariance conditions, this leads to an incorrect release other threads to see has not been created finished object. The main object is to create Holder is not atomic, may not have been constructed, other threads began to call the Holder object. 

    Since no synchronization methods to ensure it Holder object (object status contains references and are not) visible to other threads, and therefore will become unpublished Holder correctly. Holder is not the problem itself, but it is not properly released. Problems may lead to above does not release the right: 

    another thread holder for the field, you might see stale values, which would lead to a null reference, or outdated value (even if the holder has been set) (reference itself is not see other thread) 
is more frightening is that has been updated for the holder, in time to see the updated references, but for the state of the object, you can see it is likely that the old value for the above code may throw an exception AssertionError
mainly holder = new Holder (42); atomic this code is not possible when the configuration is not complete, another thread holder object reference is invoked, leading to unpredictable results.
* /

 

3. The  construction process safety target

(1) During object construction, not to publish this reference

public class EventListener { 
    public EventListener(EventSource eventSource) { 
        // do our initialization ... 
        // register ourselves with the event source 
        eventSource.registerListener(this); 
    } 
    public onEvent(Event e) { // handle the event } 
} 
public class RecordingEventListener extends EventListener { 
    private final ArrayList list; 
    public RecordingEventListener(EventSource eventSource) { 
        super(eventSource); 
        list = Collections.synchronizedList(new ArrayList()); 
    } 
    public onEvent(Event e) { 
        list.add(e); 
        super.onEvent(e); 
    } 
    public Event[] getEvents() { 
        return (Event[]) list.toArray(new Event[0]); 
    }  
} 

  If you want to create an internal class in the constructor, you can not put him in the constructor released, should be published outside the constructor, and so that is the constructor is finished, initialization has been completed, and then release the internal class.

(2) Do not implicitly expose the "this" reference

public  class EventListener2 { 
     public EventListener2 (The EventSource EventSource) {eventSource.registerListener ( 
             new new EventListener A () { 
                 public the onEvent (the Event E) { 
                    eventReceived (E); 
                } 
     }); 
    } 
    public eventReceived (the Event E) {} 
} 
is also a subclass issues

(3) Do not start threads from within constructors
     a) start a thread in the constructor, the constructor has not yet finished, is no guarantee that this object is already fully constructed
     b) If access to this object in the thread started, you can not guarantee access to the structure is totally good object

 

3.  Security issued common mode

To secure the release of an object, object references and object state must also be visible to other threads. Usually a properly constructed object (this does not occur escape constructor) can be correctly published by:

  (1) initialize an object referenced in static initializers

  (2) The reference object is stored in a volatile type of object field or AtomicReference

  (3) saves the reference in a properly constructed object final type of objects in the domain.

  (4) save the object reference to a protection domain by the lock

 

 

/ ** 
(1) There are three objects in the Java 
   a) unchanged: Object status can not be modified after creation, all domain objects is final, the object is properly constructed 
   b) is essentially the same subject: Does not immutable objects constraints, but will not change after initialization 
   c) mutable objects: immutable objects does not satisfy the above constraints and essentially the same object 

(2) security technology released 
   a) ensuring that state and object references to other thread properly visible 
   b) the way 
      static initializer to initialize the object references 
      will refer to the volatile storage domain 
      to store a reference to the correct final domain to create objects 
      store references to the domain by the lock properly protected 

(3) three kinds of objects security publishing 
   a) immutable objects: any form of mechanism published 
   b) is essentially the same target: to ensure the safety release 
   c) mutable objects: not only to ensure safe release, but also to ensure the right to change the state of an object (ie, locks or other means, to ensure the correct change object state) 
* * /

 

 

 

4. ensure container security release

  Synchronization means within the thread-safe container, place objects in a container, such as Vector, will meet the last requirements above. A thread if the object X into a thread-safe container and then thread B reads the objects, can we ensure that the state can ensure that B sees A set of X, even if this is a read / write application code without X It includes synchronous display. Provide a guarantee safe release of the vessel below:

  (1) by a key or value into the Hashtable, synchronizedMap or ConcurrentMap, you can publish it to any security thread to access it from these containers.

  (2) an element by placing Vector, CopyOnWriteArrayList, CopyOnWriteArraySet, synchroizedList, can secure the release of the element to any thread to access the elements from these containers.

  (3) by the elements into BlockingQueue or ConcrrentLinkedQueue, you can secure the release of the element to any thread to access the elements from these visits queue.

5. supplement

  In general, to publish a static object is constructed, the easiest and safest way is to use a static initializer:  public  static Holder =  new new Holder ( 42);

  Static initialization is executed by the JVM class initialization phase, due to internal synchronization mechanisms JVM, so this approach is to initialize the object can be safely released.

  For variable objects, the time of publication to ensure the safety of the 发布当时visibility states, and in each subsequent visit object, also need to use synchronization to ensure modify the operation of visibility. (+ Sync state visibility)

  

Guess you like

Origin www.cnblogs.com/haimishasha/p/11594585.html