多线程:
--并发问题
线程对于内存数据的访问会提供一个内存副本供其使用,在线程使用结束时,将副本内容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做线程安全。