Summary of Java concurrent Programming--careful use of CAs detailed _java

Source: Internet
Author: User
Tags cas

I. Applicable scenarios for CAS and synchronized

1, for less competition in resources, the use of synchronized synchronous locks for thread blocking and wakeup switching and user state kernel State switching between the operation of the additional waste of CPU resources; The CAS is based on hardware implementation, does not need to enter the kernel, does not need to switch threads, the operation Spin less chance, Therefore, higher performance can be achieved.

2, for the serious situation of resource competition, the probability of the CAS spin will be relatively large, thus wasting more CPU resources, efficiency is lower than synchronized. Taking the Atomicinteger class in the Java.util.concurrent.atomic package as an example, the Getandincrement () method is implemented as follows:

Public final int getandincrement () {for
    (;;) {
      int current = Get ();
      int next = current + 1;
      if (Compareandset (next)) return to current
        ;
    }

If the Compareandset (current, Next) method executes successfully, it is returned directly, and if the thread is fiercely competitive, causing the compareandset (current, next) method to fail to execute successfully, the loop waits. Until the time slice that the CPU allocates to the thread is depleted, resulting in a significant reduction in efficiency.

Ii. usage scenarios for CAS errors

public class Casdemo {private final int thread_num = 1000;
  Private final int max_value = 20000000;
  Private Atomicinteger CasI = new Atomicinteger (0);
  private int synci = 0;

  Private String Path = "/users/pingping/datacenter/books/linux/linux common commands in the detailed. txt";
    public void Casadd () throws interruptedexception {long begin = System.currenttimemillis ();
    thread[] threads = new Thread[thread_num];
          for (int i = 0; i < Thread_num. i++) {Threads[i] = new THREAD (new Runnable () {public void run () {
          while (Casi.get () < Max_value) {casi.getandincrement ();
      }
        }
      });
    Threads[i].start ();
    for (int j = 0; J < Thread_num; J + +) {threads[j].join ();
  System.out.println ("CAS Costs Time:" + (System.currenttimemillis ()-begin);
    public void Syncadd () throws interruptedexception {long begin = System.currenttimemillis ();
    thread[] threads = new Thread[thread_num]; For (int i = 0; i < Thread_num; 
            i++) {Threads[i] = new Thread (new Runnable () {public void run () {while (Synci < Max_value) {
            Synchronized ("Synci") {++synci;
      }
          }
        }
      });
    Threads[i].start ();
    for (int j = 0; J < Thread_num; J + +) Threads[j].join ();
  SYSTEM.OUT.PRINTLN ("Sync costs Time:" + (System.currenttimemillis ()-begin); }
}

Running on my dual-core CPU, the results are as follows:

Visible under different threads, the use of CAS calculation consumes much more time than using synchronized methods. The reason is that line 15th

While           (Casi.get () < Max_value) {             casi.getandincrement ();           }

The operation is a very small operation, 15 lines after the execution will immediately enter the loop, continue execution, resulting in thread conflict serious.

Iii. improved CAS usage scenarios

In order to solve the above problem, only need to make each time the cycle of execution longer, that is, can reduce the thread conflict greatly. Modify the code as follows:

public class Casdemo {private final int thread_num = 1000;
  Private final int max_value = 1000;
  Private Atomicinteger CasI = new Atomicinteger (0);
  private int synci = 0;

  Private String Path = "/users/pingping/datacenter/books/linux/linux common commands in the detailed. txt";
    public void CasAdd2 () throws interruptedexception {long begin = System.currenttimemillis ();
    thread[] threads = new Thread[thread_num];
          for (int i = 0; i < Thread_num. i++) {Threads[i] = new THREAD (new Runnable () {public void run () {
            while (Casi.get () < Max_value) {casi.getandincrement ();
            Try (InputStream in = new FileInputStream (new File (path)) {while (In.read ()!=-1);
            catch (IOException e) {e.printstacktrace ();
      }
          }
        }
      });
    Threads[i].start ();
    for (int j = 0; J < Thread_num; J + +) Threads[j].join (); System.out.println ("CAS Random costs Time:" + (SysTem.currenttimemillis ()-begin);
    public void SyncAdd2 () throws interruptedexception {long begin = System.currenttimemillis ();
    thread[] threads = new Thread[thread_num];
          for (int i = 0; i < Thread_num. i++) {Threads[i] = new THREAD (new Runnable () {public void run () {
            while (Synci < Max_value) {synchronized ("Synci") {++synci;
            The try (inputstream in = new FileInputStream (new File (path)) {while (In.read ()!=-1);
            catch (IOException e) {e.printstacktrace ();
      }
          }
        }
      });
    Threads[i].start ();
    for (int j = 0; J < Thread_num; J + +) Threads[j].join ();
  SYSTEM.OUT.PRINTLN ("Sync costs Time:" + (System.currenttimemillis ()-begin); }
}

In the while loop, an operation that reads the contents of a file is added, which may take 40ms to reduce thread conflicts. The test results are as follows:

It can be seen that in the case of relatively small resource conflicts, the CAs method and synchronized synchronization efficiency are similar. Why does CAs not have higher performance than synchronized?

The JDK used for the test was 1.7, and the implementation of the lock introduced a number of optimizations, such as lock coarsening, lock elimination, lightweight locks (lightweight locking), and jdk1.6. Bias lock (biased locking), adaptive spin (adaptive spinning) and other techniques to reduce the cost of lock operations. And the principle of spin lock, similar to CAS spin, even more than CAS spin more optimization. For details, please refer to the JVM lock mechanism 1-synchronized.

Iv. Summary

1. When using a CAS thread conflict severity, the program performance is significantly reduced, and CAS is only suitable for situations where there is less thread conflict.

2, synchronized after jdk1.6, has improved the optimization. Synchronized of the bottom of the implementation of the main rely on the Lock-free queue, the basic idea is the spin after blocking, competition after switching to continue to compete for the lock, a slight sacrifice of fairness, but achieved high throughput. With less thread conflicts, performance similar to CAS can be obtained, and in the case of a serious threading conflict, performance is much higher than CAs.

Above this Java concurrent programming summary--The careful use CAs detailed explanation is small arranges to share to everybody's content, hoped can give everybody a reference, also hoped that everybody supports the cloud habitat community.

Related Article

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.