java面试题 --- 并发②

1. JDK1.6 开始对 synchronized 做了哪些优化?

使用了锁升级、锁粗化、锁消除等方式来优化性能。

  • 锁升级就是先尝试偏向锁,如果没获取到锁就升级为轻量级锁,还没获取到就升级为重量级锁;
  • 锁粗化就是如果连续一系列的操作都对同一段代码反复加锁和解锁,就将加锁范围扩大,减少加解锁的次数;
  • 锁消除就是如果某一段代码加了锁但是根本不会存在并发竞争资源的问题,那么虚拟机就会把锁去掉。

2. Synchronized 和 ReentrantLock 有何异同?

  • Synchronized 是 JVM 层面的关键字,ReentrantLock 是 API 层面的;
  • Synchronized 可以修饰代码块和方法,ReentrantLock 只能用于代码块;
  • Synchronized 不需要手动释放锁,ReentrantLock 需要手动释放锁;
  • Synchronized 是非公平锁,ReentrantLock 可以通过参数指定为公平或者非公平;
  • Synchronized 等待不能中断,ReentrantLock 等待可以中断,tryLock 可以设置等待时长;
  • Synchronized 和 ReentrantLock 都是可重入锁。

3. volatile 有什么作用?

  • 它可以保证可见性,禁止指令重排,但是不能保证原子性。在 JMM 内存模型中,线程操作共享资源是先将主存中的共享资源拷贝回自己的工作内存,在工作内存中完成修改后刷回到主存,在同步回主存之前,别的线程是不知道这个值已经被改了的,这便是可见性问题。用 volatile 就可以保证一个线程对共享资源的操作对别的线程可见。JVM 编译代码的时候,会对代码做优化,使其有更好的性能,这就是指令重排。用 volatile 可以禁止指令重排。

4. final 关键字有什么特性?

  • final 修饰的对象不可变,可以保证内存的可见性,不需要额外的同步手段。

5. 说说你对 as if serial 和 happen before 的理解。

  • as if serial 就是在单线程的情况下,不管怎么指令重排,运行结果都要保持不变;
  • happen before 就是正确同步的多线程程序不管怎么指令重排运行结果要保持不变。

6. ReentrantLock 的加锁和解锁过程是怎样的?

加锁过程:

  • 加锁的时候实际上调用的是 NonfairSync/FairSync 的 lock 方法;
  • lock 方法首先调用 compareAndSetState(0, 1) 方法,如果当前 state 是0,就改成1,同时调用 setExclusiveOwnerThread 方法将持有锁线程设置为当前线程,加锁成功;
  • 如果当前 state 不是0,表示锁被别的线程持有,就用 acquire(1) 方法尝试获取锁;
  • acquire(1) 首先会用 tryAcquire(1) 方法尝试获取锁,该方法会判断 state 的值,是0,那就进行步骤2的操作;不是0但是当前线程等于正持有锁的线程,那就让 state 加1,这就是可重入原理;不是以上两种情况,那就尝试获取锁失败;
  • tryAcquire(1) 失败就会调用 acquireQueued 方法将当前线程加入到队列自旋;
  • 最后会调用 LockSupport 的 park 方法获取锁。

释放锁过程:

  • 调用的实际上是 NonfairSync/FairSync 的 release 方法;
  • release 调用的又是 tryRelease(1) 方法;
  • tryRelease(1) 会将当前 state 减1,同时把当前持有锁的线程设置为 null;
  • 最后调用 unparkSuccessor 方法,该方法里面调用 lockSupport 的 unpark 方法释放锁。

7. ReentrantReadWriteLock 怎么用一个 state 来表示读锁和写锁的状态的?

  • ReentrantReadWriteLock 读锁是共享锁,写锁是独占锁,它用 AQS 中的 state 变量的高十六位来表示读锁,值就是持有读锁的线程数量,低十六位表示写锁,值为零或者一,若是大于一,那就是重入的次数。

8. 并发的时候 List 不安全,有哪些解决办法?

  • 加锁;
  • 用 Vector;
  • 用 Collections.synchronizedList 方法;
  • 用 CopyOnWriteArrayList,它写之前会拷贝一份,写完再把引用指向拷贝的副本。

9. 你还用过哪些并发工具类?

  • CountDownLatch 等待一组线程执行完,主线程再继续执行;CycliBarriar 类似,不过 CountDownLatch 是减计数,即倒数,倒数到 0 释放所有等待的线程,调用 countDown() 方法计数减一,调用 await() 方法只进行阻塞;CycliBarriar 是加计数,即顺数,计数到指定值时释放等待线程,调用 await() 方法计数加 1,若加 1后的值不等于构造方法的值,则线程阻塞;Semaphore,构造方法传入一个 int 参数,相当于限定并发数,比如传的是 3,那么并发数只能是3。

10. 有没有了解过 ThreadLocal?

  • ThreadLocal 是用来做数据隔离的,ThreadLocal 保存的数据只对当前线程可见。用 set 方法设置数据,get 方法获取数据。原理是 Thread 类有个 ThreadLocal.ThreadLocalMap 类型的变量 threadLocals, ThreadLocal set 数据的时候,会判断当前线程类的 threadLocals 是否为空,如果为空,就会创建一个 ThreadLocalMap,然后以当前的 ThreadLocal 为 key,把 value set 进去, 并且让 threadLocals 引用指向它;如果不为空,就直接拿来用。常用于保存数据库连接,做 session、cookie 的隔离。ThreadLocal 在作为 ThreadLocalMap 的 key 时候被设计成弱引用了,但是我们 new ThreadLocal 实例的时候是强引用,所以 GC 此时并不会回收它,当 ThreadLocal 实例的生命周期结束了,没有强引用指向它了,那么它作为 ThreadLocalMap 的 key 就只有弱引用,GC 发现了就会回收它,key 被回收了,那 value 永远都用不了,就存在内存泄漏问题,解决办法就是用完之后主动调用 remove 方法。
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,491评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,856评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,745评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,196评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,073评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,112评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,531评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,215评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,485评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,578评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,356评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,215评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,583评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,898评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,174评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,497评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,697评论 2 335

推荐阅读更多精彩内容