Java学习笔记,并发编程篇

1.并发和并行

        并发:同一时间应对多件事情的能力。

        并行:同一时间动手做(执行)多件事情的能力。

        1)并发所带来的好处

                并发带来性能上的提升。提高CPU的利用率,降低系统的响应时间。

                提高系统的容错能力。一个线程可以不受其他线程的干扰独立运行,如果某个线程的代码里出现了Bug,这个线程可能抛出异常退出了,这时候其他线程可以不受任何影响继续执行,不至于导致整个系统都崩溃。

                方便代码的编写。让每个线程实现自己的策略。

2.同步和异步

        同步:需要等待结果返回,才能继续运行

        异步:不需要等待结果返回,就能继续运行

3.Java中的6种线程状态

        操作系统层面定义了5种线程状态分别为:初始状态,可运行状态(就绪),运行状态,阻塞状态和终止状态。

        Java中的6种线程状态分别为:NEW,RUNNABLE(可运行状态,运行状态,BIO的阻塞状态),TERMINATED,BLOCKED(获取不到锁,wait()竞争锁失败),WAITING(没有时间的等待,如需要等待另一个线程运行完,join(),wait(),LockSupport.park()),TIMED_WAITING(有时间的等待,如:join(long n),sleep(long n),wait(long n))。

4.线程安全问题实例

        两个线程分别自增和自减,结果不为0的原因。上下文切换导致的指令交错访问共享资源时的线程安全问题,底层字节码分析


5.局部变量的线程安全问题

        局部变量通常是线程安全的,因为局部变量通常不会产生资源共享,局部变量存放在虚拟机栈的栈帧中,而这个栈帧是由线程独享的。除非当局部变量的引用暴露时,会产生线程安全问题,如子类的重写方法中又开启了一个新的线程,这时局部变量会成为共享资源,如下图。将方法修饰符改为private不允许子类重写即可解决,类加个final修饰符不允许继承也可以解决。也可private和final修饰符在并发中的作用。


局部变量引用暴露导致线程安全问题

6.Synchronized锁优化

        锁主要存在四种状态,无锁状态、偏向锁、轻量级锁、重量级锁(Monitor),会随着竞争的强度逐渐升级,效率也会逐渐降低,其中锁可以升级但是不能降级。

        重量级锁也就是将对象与Monitor关联,主要依赖操作系统的Mutex Lock互斥量来实现的,在线程切换时效率比较低。

        轻量级锁通常发生在竞争并不激烈且多个线程交替时占用锁时,通过使用CAS操作且避免互斥量来提高效率,当多次自旋操作都没能获得锁时会升级为重量级锁。

        偏向锁通常发生在不存在竞争且一个线程多次占用锁时,通过减少CAS操作来提高效率,当发生上下文切换时会升级为轻量级锁。


7.sleep和wait的区别

        1)sleep是Thread的方法,而wait是Object的方法。

        2)sleep不需要强制和synchronize配合使用,而wait需要和synchronize配合使用,也就是说需要获得锁后才能使用,notify也是如此。

        3)sleep不会释放锁,而wait会释放锁。

        4)共同点:调用后进入的线程状态都TIMED_WAITING。

8.volatile原理

        volatile的底层实现原理是内存屏障,对volatile的写指令后会加入写屏障,对volatile的读指令前会加入读屏障。

        1)如何保证可见性?

                写屏障保证在该屏障之前的,对共享变量的改动,都同步到主存中。

                读屏障保证在该屏障之后的,对共享变量的读取,加载的是内存中的最新数据。

        2)如何保证有序性?

                写屏障保证在指令重排序时,不会将写屏障之前的代码排到写屏障之后。

                读屏障保证在指令重排序时,不会将读屏障之后的代码排到读屏障之前。

9.CAS缺点

        1)在高并发的情况下,共享变量一直被修改,会不断的循环判断,导致开销比较大。

        2)只能保证一个共享变量的原子操作。

        3)导致ABA问题(脏读),在将期望值与内存中的值比较时,虽然值相同,但是内存中的值实际已经修改了多次。虽然CAS能成功,但是内存中的值在中间是被修改过的。解决方法:用带有版本号的AtomicStampedReference。

10.线程安全的List集合类

        1)new Vector<>();

        2)  Collections.synchronizedList(new ArrayList<>());

        3)  new CopyOnWritedArrayList(),在添加元素时,也就是写的时候,先进行加锁,然后将容器数组Object[]复制一份,然后在新数组添加元素,添加完成后,将原容器的引用指向新容器。而在读的时候不需要加锁,这是一种读写分离的思想。

11.伪共享

        当多线程修改互相独立的变量时,如果这些变量共享同一个缓存行,就会无意中影响彼此的性能,这就是伪共享。


        当一个线程在对 a 进行修改,另一个线程在对 b 进行读取。这时候a和b通常会同时加载到缓存中的缓存行,更新完 a 后其它所有包含 a 的缓存行都将失效,因为其它缓存中的 a 不是最新值了。而当后者读取 b 时,发现这个缓存行已经失效了,需要从主内存中重新加载。

        解决方法:1)让不同线程操作的对象处于不同的缓存行。2)使用编译指示,强制使每一个变量对齐,一个缓存行只有一个可操作对象。

12.ThreadLocal的内存泄漏问题

        ThreadLocalMap 中使⽤的 key 为 ThreadLocal 的弱引⽤,⽽ value 是强引⽤。所以,如果ThreadLocal 没有被外部强引⽤的情况下,在垃圾回收的时候,key 会被清理掉,⽽ value 不会被清理掉。这样⼀来, ThreadLocalMap 中就会出现key为null的Entry。假如我们不做任何措施的话,value 永远⽆法被GC 回收,这个时候就可能会产⽣内存泄露。ThreadLocalMap实现中已经考虑了这种情况,在调⽤ set() 、 get() 、 remove() ⽅法的时候,会清理掉 key 为 null 的记录。使⽤完ThreadLocal ⽅法后 最好⼿动调⽤ remove() ⽅法。

13.线程池中的一个线程异常了会被怎么处理?

1.execute方法,可以看异常输出在控制台,而submit在控制台没有直接输出,必须调用Future.get()方法时,可以捕获到异常。

2.一个线程出现异常不会影响线程池里面其他线程的正常执行。

3.线程不是被回收而是线程池把这个线程移除掉,同时创建一个新的线程放到线程池中。

14.如何计算 ConcurrentHashMap Size

1.JDK1.7 和 JDK1.8 对 size 的计算是不一样的。 1.7 中是先不加锁计算三次,如果三次结果不一样在加锁。

2.JDK1.8 size 是通过对 baseCount 和 counterCell 进行 CAS 计算,最终通过 baseCount 和 遍历 CounterCell 数组得出 size。

3.JDK 8 推荐使用mappingCount 方法,因为这个方法的返回值是 long 类型,不会因为 size 方法是 int 类型限制最大值。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,033评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,725评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,473评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,846评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,848评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,691评论 1 282
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,053评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,700评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,856评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,676评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,787评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,430评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,034评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,990评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,218评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,174评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,526评论 2 343

推荐阅读更多精彩内容