Java Thread (iv): A combination of objects

Source: Internet
Author: User

to design a thread-safe class:In the process of designing a thread-safe class, you need to include the following three basic elements:
    • Identify all variables that make up the state of the object
    • Find the invariant condition of constraint state variable
    • Establishing concurrent access policies for object state
If you do not understand the invariant and posterior conditions of an object, you cannot ensure thread safety. To satisfy the various constraints on the valid values of state variables or state transitions, it is necessary to use atomic and encapsulation. If the action contains a priori condition based on the state, then this operation is called a dependent state operation, and in a concurrent program it waits until the prior condition is true before performing the operation. In Java, various built-in mechanisms that wait for a condition to be true, including the wait and notification mechanisms, are closely associated with the built-in locking mechanism.
instance closure:Encapsulating data inside an object allows data access to be restricted to the methods of the object, making it easier to ensure that threads always hold the correct locks when accessing data. Example: ensuring thread safety through a closed mechanism
@ThreadSafepublic class Personset {     @GuardedBy ("This")     private final set<person> MySet = new hashset< Person> ();     Public synchronized void Addperson (person p) {          myset.add (p);     }     Public synchronized Boolean Containsperson (person p) {          return myset.contains (p);     }     }
Since MySet is private and does not overflow, the state of Personset is completely protected by its built-in lock, and thus personset is a thread-safe class.a closed mechanism is easier to construct a thread-safe class, because when the state of a class is closed, it is not necessary to examine the entire program when parsing the thread security of the class. Usually we can also use a private lock to protect the state.
public class privatelock{     private Final Object myLock = new Object ();     @GuardedBy ("MyLock") widget widget;     void SomeMethod () {          synchronized (myLock) {               //Access or modify the widget's status          }}     }     
Thread-Safe delegates:     if a class consists of multiple independent, thread-safe state variables and does not contain invalid state transitions in all operations, then thread security can be delegated to the underlying state variable. Example: Here we implement a vehicle tracker that can return a vehicle's current position in real time or modify the location of a vehicle.
@Immutablepublic class Point {public     final int x, y;     public point (int x, int y) {          this.x = x;          This.y = y;     }} @ThreadSafepublic class Delegatingvehicletracker {     private final concurrentmap<string, point> locations;          Public Delegatingvehicletracker (map<string, point> points) {           locations = new Concurrenthashmap<string, Point> (points);     }     Public map<string, Point> getlocations () {          return Collections.unmodifiablemap (               new hashmap<string , point> (locations)          };     }     Public point getLocation (String id) {          return locations.get (ID);     }     public void setlocation (String ID, int x, int y) {          if (Location.replace (ID, new Point (x, y) = = null)               throw new I Llegalargumentexception (                    "Invalid vechicle name:  " + ID);}     }       
If there is a connection between multiple state variables of a class, such as maintaining some kind of invariance condition, then it is not easy to delegate thread security to the underlying variable. Example: The Numberrange class is not enough to protect its invariance condition
public class Numberrange {     //invariance condition: Lower <= upper     private final Atomicinteger lower = new Atomicinteger (0); 
   private final Atomicinteger upper = new Atomicinteger (0);     public void Setlower (int i) {     //Note: unsafe "perform after first check"          if (i > Upper.get ()) {               throw new illegalargumentexception (                         "can ' t set lower to" + i + "> upper");          }          Lower.set (i);     }     public void Setupper (int i) {          if (I < Lower.get ())               throw new IllegalArgumentException (                         "can ' t set upper To "+ i +" < lower ");     }     public boolean isinrange (int i) {          return (I >= lower.get () && i <= upper.get ());}     }

If a class contains composite operations, such as Numberranger, then near-reliance on delegates is not sufficient for thread safety. In this case, the class must provide its own locking mechanism to ensure that these compound operations are atomic operations, unless the entire composite operation can be delegated to the state variable.If a state variable is thread-safe and does not have any invariant conditions to constrain its value, there is no state transition that is not allowed in the operation of the variable, so it is safe to publish the variable. Example: we show how to publish a bottom-level variable by modifying an example of a previous vehicle tracker
@ThreadSafepublic class SafePoint {@GuardedBy ("this") private int x, y;     private SafePoint (int []a) {This (a[0], a[1]);}     Public SafePoint (SafePoint p) {This (P.get ());}          public safepoint (int x, int y) {this.x = x;     This.y = y;     } public synchronized int[] Get () {return new int[] {x, y};          } public synchronized void set (int x, int y) {this.x = x;     This.y = y;          }} @ThreadSafepublic class Publishingvehicletracker {Private final concurrentmap<string, point> locations; Public Delegatingvehicletracker (map<string, point> points) {locations = new Concurrenthashmap<str     ING, point> (points); } public map<string, Point> getlocations () {return Collections.unmodifiablemap (new have     Hmap<string, point> (locations)};     Public point getLocation (String ID) {return locations.get (ID); } public void setlocation(String ID, int x, int y) {if (!location.containskey (ID)) throw new IllegalArgumentException ("Invalid ve          Chicle Name: "+ ID");     Locations.get (ID). set (x, y);   }}
to add functionality from an existing thread-safe class:The Java class Library contains a number of useful "base module" classes.     Sometimes, an out-of-the-box thread-safe class can support all the operations we need, but more often, the existing class intelligence supports most of the operations, and you need to add a new operation without breaking the thread's security. For example, suppose a thread-safe linked list is required, and it needs to provide an atomic "add (put-if-absent)" operation. The safest way to add a new atomic operation is to modify the original class, but this is usually not possible. Another way is to extend this class:
@ThreadSafepublic class Bettervector<e> extends vector<e> {public     synchronized Boolean putifabsent (E x {          Boolean absent =!contains (x);          if (absent)                Add (x);          return absent;}     }     
client lock mechanism:The third strategy is to extend the functionality of the class, but not to extend the class itself, but instead to put the extension code in a "helper class". Example-using a client lock to implement "add if not"
@ThreadSafepublic class Listhelper<e> {public     list<e> List =                collections.synchronizedlist (new Arraylist<e> ());     ...     public boolean putifabsent (E x) {          synchronized (list) {                Boolean absent =!list.contains (x);                    if (absent)                    list.add (x);                return absent;}}     }
for client-side code that uses an object x, protect this customer code with the lock that X itself uses to protect its state. To use a client lock, you must know which lock the object x is using.       Combination:      When adding an atomic operation to an existing class, there is a better way to do this: combine. In the following example, Improvedlist implements the list operation by delegating the operation of the list object to the underlying list instance, and also adds an atomic Putifabsent method.
@ThreadSafepublic class Improvedlist<t> implements list<t> {     private final list<t> List;     Public improvedlist (list<t> list) {this.list = list;}     Public synchronized Boolean putifabsent (T x) {          Boolean contains = List.contains (x);          if (contains)               list.add (x);          return!contains;     }     Public synchronized void Clear () {list.clear ();}     //... Other ways to delegate the list in a similar way}
The improvedlist adds an extra layer of lock through its own built-in lock, and the extra sync layer can cause slight performance loss, but the loss is still small. (because there is no more competition on the bottom list)

Java Thread (iv): A combination of objects

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.