大年初一,一起嗨起来!!!
强调一句很重要的心里话:祝大家在 2021 年,健康好运,平安幸福!
问题描述用两个线程,一个输出数字,一个输出字母,交替输出 1A2B3C4D...26Z
该如何实现?
解决方式据说解决方式有上百种,但有些是脱了裤子放屁,有些是民间偏方,所以没必要全部都知道(其实楼主也不知道具体是哪一百多种)
掌握常用的那几个就好;为了方便,我们就以 1234567 和 ABCDEFG 为例进行演示
synchronized + wait + notify如果我们对 JUC 不熟的话,那这种方式往往是我们最容易想到的
这种方式,相信大家都能写出来,但是这里留三个问题(面试点)
1、线程代码中, try 中的 notify() 能否与 wait() 交换位置,为什么
2、线程代码中, for 下的 notify() 能否去掉,为什么
3、上面的代码能否保证一定先输出数字,为什么,如何保证一定先输出数字
ReentrantLock + Condition + await + signal很多场景下,用 ReentrantLock 可以替代 synchronized ,而在交叉输出这个场景中,同样可以替代
这种方式,写出来应该也不难,同样留三个问题(面试点)
1、线程代码中, for 中的 signal() 能否与 await() 交换位置,为什么
2、线程代码中, for 下的 signal() 能否去掉,为什么
3、上面的代码能否保证一定先输出数字,为什么,如何保证一定先输出数字
LockSupport + park + unpark估计很多人都没想到这种方式,直接上代码
这是目前最优的解决方式,照样留四个问题(面试点)
1、 t1.start() 能否与 t2.start() 交换位置,为什么
2、线程 t1 中的 LockSupport.unpark(t2) 在线程 t2 中的 LockSupport.park() 之前执行会怎么样,为什么
3、上面的代码能否保证一定先输出数字,为什么
4、 LockSupport 的 park 、 unpark 与 Object 的 wait 、 notify 有什么异同
CAS这种方式可能也比较难想到,直接上代码
这种方式也许不太好理解,留四个问题(面试点)加深理解
1、线程代码中, while 条件为什么是 !=,而不是 ==
2、上面的代码能否保证一定先输出数字,为什么
3、CAS 的优缺点是什么,适用于什么场景
CAS + AtomicInteger其实就是 CAS 的一个变种,直接上代码
CAS + AtomicReference也是 CAS 的一个变种,直接上代码
TransferQueue一般很难想象到这种方式,但却是很有趣的一种实现方式