面试场景
面试官:Java多线程了解吗?你给我写一下,起两个线程交替打印0~100的奇偶数。
小黄:啊?
面试官:就是有两个线程,一个线程打印奇数另一个打印偶数,它们交替输出,类似这样。
偶线程:0
奇线程:1
偶线程:2
……
奇线程:99
偶线程:100
小黄:啊?
面试官:……嗯。好的。回去等通知吧。
解说
遇到这种突如其来的面试题,有时候会让人无从下手。尽管可能你学习过多线程的知识,但是面试官抛一个问题过来,短时间内可能想不出如何使用这些知识来解决这个具体的问题。其实这个问题考察的知识点并不难,但是如果准备的面试的时候没有看过这道题,一时间还是比较难想出解决方案来的,而且这种题往往是让面试者手写代码。
回到题目上来。首先是两个线程,其次是交替打印。这可以联系到线程之间的通信问题。这时可以想到大致的方向就是加锁,哪个线程拿到锁就打印,然后释放锁让另一个线程获取锁。两个线程轮流拿到锁,实现交替打印的效果。
起两个线程大家都会,加锁也简单,问题是如何让这两个线程轮流拿到锁呢?我们知道,加锁之后线程之前相互竞争锁,而Java默认是不保证锁的公平性的(使用公平锁可能也是一个思路),这就有可能出现同一个线程一直打印而另一个线程一直没有打印的情况。
讨巧的方案
比较容易想的一个方案是,要输出的时候判断一下当前需要输出的数是不是自己要负责打印的值,如果是就输出,不是就直接释放锁。