分享一道多线程面试题,只是拿来练手的,这里通过两种方式去实现0-100交替打印,大家无聊的话,可以瞅两眼。
一、Synchronized实现:
public class PrintNumberIncrInSynchronized {
private static int number;
private static final Object object = new Object();
public static void main(String[] args) {
new Thread(() -> {
while (number < 100) {
synchronized (object) {
//相对%2判断奇偶数,&效率更高
if ((number & 1) == 0) {
System.out.println(Thread.currentThread().getName() + ":" + number++);
}
}
}
},"偶数").start();
new Thread(() -> {
while (number < 100) {
synchronized (object) {
if ((number & 1) == 1) {
System.out.println(Thread.currentThread().getName() + ":" + number++);
}
}
}
},"奇数").start();
}
}
启动两个线程,分别进行进行命名,并且只打印奇数和偶数。通过不断竞争monitor锁,只有满足if判断才会++和打印,最终能够实现要求。从实现过程能够看出来,需要不断竞争锁,而且很有可能不满足条件,不够高效。
二、wait和notify实现:
public class PrintNumberIncrInWaitAndNotify {
private static int number;
private static final Object object = new Object();
public static void main(String[] args) throws InterruptedException{
new Thread(new ToolClass(), "偶数").start();
//这里休眠10ms保证偶数线程能够先执行
Thread.sleep(10);
new Thread(new ToolClass(), "奇数").start();
}
static class ToolClass implements Runnable {
@Override
public void run() {
while (number <= 100) {
synchronized (object) {
System.out.println(Thread.currentThread().getName() + ":" + number++);
object.notify();
try {
object.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
}
每次进行++操作并且打印之后,就会notify唤醒另一个因为wait()陷入Waiting状态的线程,然后调用wait(),释放monitor锁,另一个线程获取到锁,进行同样的操作,最终实现要求。