Talk about high concurrency (vi) Realization of several spin locks (i)

Source: Internet
Author: User
Tags cas mutex rollback advantage

Talking about high concurrency (v.) Understanding of Cache consistency protocol and its impact on concurrent programming we understand the principle of the processor cache consistency protocol, it also refers to its impact on concurrent programming, "Multiple threads have been using CAs for the same variable, so there will be a lot of modifications, resulting in a lot of cache consistency traffic, Because each CAS operation emits a broadcast notification to other processors, which affects the performance of the program. ”


In this article we have two ways to achieve the spin lock to see the different programming methods brought about by the changes in program performance.


First understand what is the spin, the so-called spin is a thread in the case of not satisfying a certain condition, has been looping to do some action. So for a spin lock to lock, when the thread is not acquiring a lock, the loop attempts to acquire the lock until the lock is actually acquired.


Talking about some basic concepts of high concurrency (iii) lock we mentioned that the nature of the lock is to wait, then how to wait, there are two ways

1. Thread Blocking

2. Thread Spin


The disadvantage of blocking is obvious, once the thread has entered the blocking (block), the higher the cost of awakening, poor performance. The advantage of spin is that the thread is still runnable, just executing the empty code. Of course, the spin will also be used in vain computing resources, so the common practice is to spin for a period of time, not to get the lock into the block. The JVM uses this eclectic approach when dealing with synchrized implementations and provides parameters to adjust the spin.


This article explains the two most basic spin-lock implementations, and provides an optimized lock, followed by more spin-lock implementations.


First is Taslock (test and set lock), testing-Set the lock, it is characterized by spin, each attempt to acquire a lock, the use of CAS operation, constantly set the lock flag bit, when the lock flag bit available, one thread to get the lock, other threads continue to spin.

The disadvantage is that the CAS operation has been modifying the value of the shared variable, causing a cache-consistent traffic storm

Package com.test.lock;

Lock interface Public
interface Lock {public
void Lock ();
public
void Unlock ();
}




Package com.test.lock;

Import Java.util.concurrent.atomic.AtomicBoolean;

/**
 * Test-set spin lock, save state with Atomicboolean atomic variable
 * Every time you use the Getandset atomic operation to determine the lock state and try to acquire
 the lock * The disadvantage is that the Getandset bottom is implemented using CAs. The value of the shared variable has been modified to raise the cache consistency traffic Storm
 * **/public
class Taslock implements lock{
	private Atomicboolean mutex = new Atomicboolean (false);
	
	@Override
	the public void Lock () {
		//Getandset method sets the mutex variable to TRUE and returns the value before the mutex
		//When the mutex is false before returning, Indicates that the acquire lock
		//Getandset method is atomic and the change of the mutex atom variable is visible to all threads while
		(Mutex.getandset (True)) {
			
		}
	}

	@ Override public
	void Unlock () {
		mutex.set (false);
	}

	Public String toString () {return
		"Taslock";
	}
}

An improved algorithm is Ttaslock (test test and set lock) testing-testing-setting locks, the feature is that when a spin attempts to acquire a lock, it is divided into two steps: The first step is to acquire the lock state by reading, and when the lock is available, the second step is to attempt to acquire the lock by the CAS operation, Reduces the number of operations for CAs. And the first step of the read operation is the processor directly read its own cache, does not generate cache consistency flow, does not occupy the bus resources.

The disadvantage is that in the case of lock high contention, it is difficult for a thread to acquire a lock at a time, and the operation of CAs can be greatly increased.

Package com.test.lock;

Import Java.util.concurrent.atomic.AtomicBoolean;

/**
 * Test-test-set spin lock, use Atomicboolean atomic variable to save state
 * is divided into two steps to obtain the lock
 * 1. The first attempt to acquire the lock * 2 by means of the read variable spin.
 when it is possible to acquire a lock, Using the Getandset atomic operation to try to acquire the lock
 * Advantage is the first step is to use read variables to acquire the lock, cache the operation inside the processor, do not generate cache consistency Traffic
 * The disadvantage is that when the lock contention is fierce, the first step is not to get the lock, Getandset the bottom layer is implemented using CAs to modify the value of the shared variable all the time, raising the cache consistency traffic Storm
 * **/public
class Ttaslock implements lock{

private Atomicboolean Mutex = new Atomicboolean (false);
	
	@Override public
	void Lock () {
		while (true) {
			//The first step is to use a read operation, attempt to acquire a lock, and exit the loop when the mutex is false, indicating that the lock while
			( Mutex.get ()) {}
			//second uses the Getandset method to attempt to acquire the lock
			if (!mutex.getandset (True)) {return
				;
			}	
			
		}

	} @Override public
	void Unlock () {
		mutex.set (false);
	}

	Public String toString () {return
		"Ttaslock";
	}
}

For the lock high contention problem, you can take a fallback algorithm, that is, when the thread did not get the lock, wait a while to try to acquire the lock, which can reduce the contention of the lock, improve the performance of the program.


Package com.test.lock;

Import Java.util.Random;
	
	/** * fallback algorithm, reduce the probability of lock contention * **/public class Backoff {private final int mindelay, maxdelay;
	
	private int limit;
	
	Final Random Random;
		public backoff (int min, int max) {this.mindelay = min;
		This.maxdelay = max;
		Limit = Mindelay;
	Random = new Random ();
		//fallback, thread waits for a period of time public void Backoff () throws interruptedexception{int delay = random.nextint (limit);
		Limit = Math.min (maxdelay, 2 * limit);
	Thread.Sleep (delay);

}} package Com.test.lock;

Import Java.util.concurrent.atomic.AtomicBoolean; /**  * Rewind spin lock, increased thread fallback on test-test-set spin lock, lower lock contention  * The advantage is that lock contention is reduced in the case of high contention, and performance is improved  * the drawback is that the time for rollback is difficult to control, Constant testing is required to find the right value and relies on the performance of the underlying hardware, poor scalability  * **/public class Backofflock implements lock{    private final in
T Min_delay, Max_delay;          public backofflock (int min, int max) {        min_
DELAY = min;         max_delaY = max;
   &nbsp}          private Atomicboolean mutex = new Atomicboolean (false);           @Override     public void Lock () {      
 //Add Fallback object         backoff backoff = new Backoff (Min_delay, Max_delay);         while (True) {            // The first step is to use the read operation, attempt to acquire the lock, and exit the loop when the mutex is false, indicating that the lock             while (mutex.get) can be acquired ( ) {}             //The second part uses the Getandset method to try to acquire the lock              if (!mutex.getandset (True)) {          
     return;             }else{                //fallback                 try {          
         backoff.backoff ();                &nbsp} catch (Interruptedexception e) { & nbsp              }            & nbsp;}                          &nbsp} & nbsp;  &nbsp}      @Override     public void Unlock () {     &nbs P
 mutex.set (FALSE);    &nbsp}     public String toString () {        return "
Ttaslock ";    &nbsp}}  

The problem with the rollback spin lock is that the rollback time is difficult to control, requiring constant testing to find the right value, and depending on the performance of the underlying hardware and poor scalability. A better spin-lock implementation algorithm will be available later.


Below we test the performance of Taslock and Ttaslock.

First, write a timer class

Package com.test.lock;

public class Timecost implements lock{

	private final lock lock;
	
	Public Timecost (lock Lock) {
		This.lock = lock;
	}
	
	@Override public
	void Lock () {
		Long start = System.nanotime ();
		Lock.lock ();
		Long Duration = System.nanotime ()-Start;
		System.out.println (lock.tostring () + "time Cost is" + Duration + "ns");
	}

	@Override public
	void Unlock () {
		lock.unlock ();
	}

}

Multiple threads are then used to simulate contention for the same lock


Package com.test.lock;

public class Main {
	private static timecost timecost = new Timecost (new Taslock ());
	
	private static Timecost Timecost = new Timecost (new Ttaslock ());
	
	public static void Method () {
		timecost.lock ();
		int a = ten;
		Timecost.unlock ();
	}
	
	public static void Main (string[] args) {for
		(int i = 0; i < i + +) {
			thread t = new Thread (new Runnable () { c11/> @Override public
				void Run () {method
					();
				}
				
			});
			T.start ();}}



The performance of the test machine is as follows:

Cpu:4 Intel (R) Core (TM) i3-2120 CPU @ 3.30GHz

Memory: 8G


Test results:

50 Threads:

Taslock average time to acquire a lock: 339715 NS

Ttaslock average time to acquire a lock: 67106.2 NS


100 Threads:

Taslock average time to acquire a lock: 1198413 NS

Ttaslock average time to acquire a lock: 1273588 NS


You can see that ttaslock performance is better than taslock performance

Reprint please indicate the source: HTTP://BLOG.CSDN.NET/ITER_ZC












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.