多线程:

--并发问题

线程对于内存数据的访问会提供一个内存副本供其使用,在线程使用结束时,将副本内容merge到内存中。以下的图就是线程并发的问题。

数据1被线程1和线程2都拿走各拿的都是一个拷贝的副本,这个时候都对数据+1,在结束时副本数据都为2,本来应为3,merge后数据也为2。

voliate 修饰词:

           强制从内存中获取,如果有变更则直接更新内存,可以大范围的解决并发冲突,但是不能完全消除掉。

synchronized:

         表示将内存给锁住,一次只能有一个线程去取,取完了再下一个,这样保证安全,但是会造成堵塞。

目前java7,8用的较新的有:

1.  AtomicInteger 做计数用,内部使用voliate和Unsafe类。

对于UnSafe类,内部修饰符都是native即会调用系统语言操作内存,有指针的引入。其中pack()和unpack()控制线程的挂起还是继续。

CAS ---比较并交换(compare and swap)是一条CPU并发

CAS方法控制对CPU原子指令操作,保证顺序执行并不会被打断实现免疫死锁。

但ABA问题就需要使用AtomicStampedReference类加入时间戳来判断是否内存的数据有没有过改动。

Lock和unLock也就是通过 调用CAS将要锁的对象预期值设为null,使得无法进入cpu处理,然后会在门外排队等候,等到自己又被排除掉。

只有被unlock后,通过线程循环将预期值设为当前线程,使得cpu可以处理。

详细参考文章:https://blog.csdn.net/mmoren/article/details/79185862

2. ConcurrentHashMap 内部分有16个分片,各分片内部是线程保护,可对应最多16个线程的同时访问。

    如果线程数过大则要用HashTable和synchronized做线程安全。

 

posted on 2020-03-11 12:56  zhaoqiang1980  阅读(242)  评论(0编辑  收藏  举报