jdk源码——集合(ConcurrentHashMap)

     看这个集合的源码时,内心是拒绝的,六千多行的代码量,够我们看一段时间的。ConcurrentHashMap使线程安全的,底层是散列表+红黑树,线程安全不是在方法上使用synchronize关键字,使用了两种方式,第一是锁分段,第二是一个CAS算法。

    jdk1.8之前使用的是锁分段机制,jdk1.8之后,变为CAS算法。

   简单说一下,锁分段机制,嗯,意思就是这么个意思。每个段中都有一个散列表。每一个段都是一个segments,每个segments都是都一个锁。

 


       在jdk1.8之后使用的CAS算法效率更高,因为没有了上下文的切换,节省了时间。

       CAS(Compare and swap比较和交换)算法,是一种很有名无锁算法。是一种无所的非阻塞算法的实现

       CAS算法:包含了三个操作数,

                              需要读写的内存值V,预估的值A,替换的新值B

                              当且仅当V的值等于A时,CAS通过原子方式用新值B来更新V的值,否则不会有任何操作

       大概意思就是,我们要替换时,需要调用方法,compare(int A,int B),所以必须设置一个预估值,预估值,从何出来,会有一个方法提供内存值V,获得V值,将其传入到compare方法中,在这个方法中,比在此比较V 和A的值,如果相等,则可以替换。因为内存值没有改变,所以线程安全。

       这是一个模拟的CAS算法。意思就是这么个意思。

public class CompareSwapModel {
	
	public static void main(String[] args) {
		
		final Comswap comswap=new Comswap();
		
		for(int i=0;i<10;i++){
			
			new Thread(new Runnable() {
				
				@Override
				public void run() {
					
					int A=comswap.get();
					System.out.println(comswap.compareswapset(A, 9));
				}
			}).start();	
		}
	}
}
	
//当然CAS算法中并不是使用的是synchronized关键字,他是对硬件的调用,而我们模拟使用的synchronized关键字,是对模拟器的调用
	class Comswap{
		private int value ;//内存值
		
		public synchronized int get(){
			return value;
		}
		
		//比较
		public synchronized int compareswap(int expectedVlue ,int newValue){
			int oldavlaue=value;
			
			if(oldavlaue==expectedVlue){
				//如果两个相等
				this.value=newValue;
			}
			return oldavlaue;
		}
		
		//设置
		public synchronized boolean compareswapset(int expectedVlue ,int newValue){
			
			return expectedVlue==compareswap(expectedVlue,newValue);
		}
	}

       问题:CAS算法,是一个无锁算法,是不是其中就是没有锁?

           回答是,不是的,他依然使用了synchronize关键字,hash值相同的链表的头结点还是会synchronized上锁。


         还有一个关键字,volatile,volatile仅仅用来保证该变量对所有线程的可见性,但不保证原子性。

    可见性:在多线程的环境下:当这个变量修改时,所有的线程都会知道该变量被修改了,也就是所谓的“可见性”

    不保证原子性:修改变量(赋值)实质上是在JVM中分了好几步,而在这几步内(从装载变量到修改),它是不安全的

     其实这一篇,就是简单的介绍,我是没有能力将ConcurrentHashMap分析的多好。所以,大家还是尽量在网上多找一些资料,多看一些大牛写的分析看一下吧,我其实很多时候,也是在网上搜索的。。。

     算了,以后再写吧,我自己看源码,很多东西,都处于懵逼状态。嗯,没办法了。

    ---------未完待续,这一篇的更新时间,不确定,有可能几个星期以后,或者更长时间。。。。。

    不过。我在网上看了一篇文章,讲的很好,在这里附有链接,大家可以看一下。

   ConcurrentHashMap原理分析

    大家可以看一下,我就是看的这一篇,共同学习。面试的时候,我在网上看的,一个帖子,他说特面试的时候问到ConcurrentHashMap的size()方法,是如何计算ConcurrentHashMap的大小的。

  

    下面一个阶段,应该会分析一下线程吧!毕竟线程在面试的时候,会占的比重较大。

    

     

    

    

 

猜你喜欢

转载自blog.csdn.net/qq_36838854/article/details/80378392