java concurrent critical resource management

The so-called concurrent, generally refers to a hardware-based multi-processor environment, at the same time allows the system to perform different tasks logic pieces, a single processor hardware environment, generally in accordance with the round-robin scheduling, to achieve macroscopic sense concurrency, and in fact, on the same point in time, only one task is still running, I used to call this concurrency as "pseudo-concurrency", talking about the following concurrent critical resource management, it is based on multi-CPU hardware environments of. That is, at the same time, different CPU running might visit some of the shared resources, and critical resource management needs to do is ensure these resources can not read and write operations and a deadlock, each thread gets the resources are up to date. 

Before concurrent mentioned, I have to mention a basic problem, that is, at run time, in order to speed up the processing speed, temporary data is generally placed in CPU cache (Cache) in, and different thread owns some different the Cache, so here it involves a problem that for shared resources, how to ensure the synchronization of all the threads read and write. This is the reason the critical resource management problems to be solved concurrently. java concurrency solution to this problem is based on the following principles: to ensure that each thread is exclusive of the write operation to a shared resource, and will change the shared resource is written back to main memory (memory), a rules-based cache coherency, Cache sharing the same values ​​for all resources in the system will be fully expired, other threads are forced to read from the main memory to the value. (Hardware, not elaborate) 

 A. Implement multi-threaded Java 

Java Multiple Threads from the language is by instantiating the Thread class, call the instance start () method to perform its tasks run () method defined to achieve. Get our own Thread instance, there are two ways, one is to make their task a parent class inheritance Thread class and override its run method, the last instance of this class assignment, call the start () method to start the thread.

 Another method is the task class inherits Runnable interface, and achieve its run () method, by Thread myThread = new Thread (myRunnable), passing the Runnable instance constructor argument as to obtain a Thread instance, calls start () method, start a thread. This approach is more commonly used.

 Two ways mentioned above, needs to obtain an instance of class Thread display, and the operation and management for each individual Thread. However, when more needed to build a thread, in this way it seems to be rather complicated, because the issue of occupation and release system resources are handed over to our designers, it also offers a similar Java thread pool management approach to managing these threads. These management tools in java.util.concurrent package. By ExecutorService examples, the Thread management package further details by calling its execute () method, thread of execution, and by shutdown () mode, which freed all the resources occupied by threads. Its common code as follows :( recommended) 

 ExecutorService es = Executors.newCachedThreadPool (); // get the thread pool 

 for(int i=0;i<5;i++){ 

       es.execute (new Accessor (i)); // thread of execution 

 }

 TimeUnit.SECONDS.sleep(5); 

 es.shutdown (); // release all resources 

Acquiring thread pool of three ways, namely, 

Executors.newCachedThreadPool (): thread pool size equal to the actual number of threads created Executors.newFixedThreadPool (int num): create a thread pool Executors.newSingleThreadExecutor fixed size (): fixed thread pool size to 1 

 II. Critical Resource Management 

This part involves several common keywords, a is the synchronized, is a volatile, a series of atoms is Atomatic * class, and the ThreadLocal (thread local storage). 

 1. volatile 

This keyword is used to modify a variable, its function and affects only need to remember a word, it guarantees that the modified its variable values ​​after each change, will instantly refresh value changes written to the primary memory. 

Its limitations is also here, he can only guarantee the synchronous variable, rather than functional synchronization. For example, the volatile variables i, i ++ perform the operation; this operation is not thread-safe, because this operation is not atomic, it can be split into two steps, one step is to read the value of i, the second step is to do an adder; volatile the first step can only guarantee a certain value was read to date, but before the second step, the thread may be temporarily suspended, and then to perform other thread, if another thread at this point to modify the value of i, the second step then calculated the value of the not so reasonable. So functional synchronization is synchronized keyword of the things. 

 2. synchronized 

This is the most commonly used Java Concurrency ensure the synchronization of a keyword. Use the keywords to ensure synchronization is achieved by locking mechanism can also be said to be an implicit lock mode, that being said, because you can use the Lock java.util.concurrent.locks library provided class displays the code blocks in order to achieve locking thread synchronization.

 Each object in Java can be used as a lock, the lock here are two operations for locking and unlocking it, that at most only one thread at a time can access the object as a lock. The use of synchronized: synchronized can be used to modify the conventional method, a static method and a code block manifestation of the following three locks: 

For normal synchronization method, the lock is the current instance of the object; static synchronization method, the lock is Class object of the current class; for block synchronization method, the lock object parameter specifies a synchronized parentheses. 

There are two things should be noted about the synchronized: 

(1) for a particular subject, all synchronized methods which share the same lock, i.e. when a member of the class contains a plurality Synchronized modification method, an instance of an object class, one can only access the same time members of the method, the synchronization code block, the same rule holds. 

Part (2) synchronized key signatures are not method, it is possible to add before overwriting method. 

 3. atoms class 

It needs to be noted that the atomic operation refers not be interrupted thread scheduling mechanism operate. Atomic operation is simple can be used in addition to long and double above all basic types, i.e. values ​​for the read and write operations other than long and double base type variable is an atomic operation. However, due to long and double 64bit data, and the JVM 64 are read and write as two separate 32-bit operation is performed, which may be generated a context switch among the hidden read and write operations occur , leading to the possibility of an incorrect result, which is also known as word tear. Therefore Java SE5 atoms introduced special variables such as AtomicInteger, AtomicLong AtomicReference and the like, and provides a corresponding method of reading and writing, to ensure that atomic read and write operations. Specific reference manual, its library is java.util.concurrent.atomic. 

 4. ThreadLocal 

Quote from "Java Programming programming ideas" -. "The second way to prevent the task conflict on the shared resource is shared variables eradication of thread local storage is an automated mechanism can be different for each use the same variables threads are created different storage. So, if you have five threads must be represented using the object variable X, then thread local storage will generate five different memory blocks for the X's. ", and create and manage threads local java.lang.ThreadLocal storage class can be realized. 

 Which provides the following sample code: 

 /** 

 * Created by Song on 2016/10/15. 

 */

 public class ThreadLocalVariableHolder {

      private static ThreadLocal<Integer> values = new ThreadLocal<Integer>(){ 

        private Random rand = new Random(47); 

       @Override 

       protected synchronized Integer initialValue() { 

              return rand.nextInt(10000); 

        } 

 }; 

 public static void increment(){ 

 values.set(values.get()+1); 

 } 

 public static int get(){return values.get();} 

 public static void main(String [] args) throws InterruptedException{ 

        ExecutorService es = Executors.newSingleThreadExecutor(); 

        for(int i=0;i<5;i++){ 

              es.execute(new Accessor(i)); 

        } 

        TimeUnit.SECONDS.sleep(5); 

        es.shutdown(); 

    } 

}

 class Accessor implements Runnable{ 

      private final int id; 

      public Accessor(int id){this.id=id;} 

      public void run() { 

          while (!Thread.currentThread().isInterrupted()){                     ThreadLocalVariableHolder.increment(); 

System.out.println(this); Thread.yield(); 

    } 

 } 

 public String toString(){ 

       return "#"+id+": "+ThreadLocalVariableHolder.get();

   }

 } 

Reproduced in: https: //juejin.im/post/5cedfda1f265da1ba84a729e

Guess you like

Origin blog.csdn.net/weixin_34399060/article/details/91438973