并发和多线程(六)--实现两个线程从0-100交替打印
分享一道多线程面试题,只是拿来练手的,这里通过两种方式去实现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(); } }
结果: 偶数:0 奇数:1 偶数:2 奇数:3 偶数:4 奇数:5 偶数:6 奇数:7 偶数:8 奇数:9 偶数:10 奇数:11 偶数:12 奇数:13 偶数:14 奇数:15 偶数:16 奇数:17 偶数:18 奇数:19 偶数:20 奇数:21 偶数:22 奇数:23 偶数:24 奇数:25 偶数:26 奇数:27 偶数:28 奇数:29 偶数:30 奇数:31 偶数:32 奇数:33 偶数:34 奇数:35 偶数:36 奇数:37 偶数:38 奇数:39 偶数:40 奇数:41 偶数:42 奇数:43 偶数:44 奇数:45 偶数:46 奇数:47 偶数:48 奇数:49 偶数:50 奇数:51 偶数:52 奇数:53 偶数:54 奇数:55 偶数:56 奇数:57 偶数:58 奇数:59 偶数:60 奇数:61 偶数:62 奇数:63 偶数:64 奇数:65 偶数:66 奇数:67 偶数:68 奇数:69 偶数:70 奇数:71 偶数:72 奇数:73 偶数:74 奇数:75 偶数:76 奇数:77 偶数:78 奇数:79 偶数:80 奇数:81 偶数:82 奇数:83 偶数:84 奇数:85 偶数:86 奇数:87 偶数:88 奇数:89 偶数:90 奇数:91 偶数:92 奇数:93 偶数:94 奇数:95 偶数:96 奇数:97 偶数:98 奇数:99 偶数:100
启动两个线程,分别进行进行命名,并且只打印奇数和偶数。通过不断竞争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(); } } } } } }
结果: 偶数:0 奇数:1 偶数:2 奇数:3 偶数:4 奇数:5 偶数:6 奇数:7 偶数:8 奇数:9 偶数:10 奇数:11 偶数:12 奇数:13 偶数:14 奇数:15 偶数:16 奇数:17 偶数:18 奇数:19 偶数:20 奇数:21 偶数:22 奇数:23 偶数:24 奇数:25 偶数:26 奇数:27 偶数:28 奇数:29 偶数:30 奇数:31 偶数:32 奇数:33 偶数:34 奇数:35 偶数:36 奇数:37 偶数:38 奇数:39 偶数:40 奇数:41 偶数:42 奇数:43 偶数:44 奇数:45 偶数:46 奇数:47 偶数:48 奇数:49 偶数:50 奇数:51 偶数:52 奇数:53 偶数:54 奇数:55 偶数:56 奇数:57 偶数:58 奇数:59 偶数:60 奇数:61 偶数:62 奇数:63 偶数:64 奇数:65 偶数:66 奇数:67 偶数:68 奇数:69 偶数:70 奇数:71 偶数:72 奇数:73 偶数:74 奇数:75 偶数:76 奇数:77 偶数:78 奇数:79 偶数:80 奇数:81 偶数:82 奇数:83 偶数:84 奇数:85 偶数:86 奇数:87 偶数:88 奇数:89 偶数:90 奇数:91 偶数:92 奇数:93 偶数:94 奇数:95 偶数:96 奇数:97 偶数:98 奇数:99 偶数:100
每次进行++操作并且打印之后,就会notify唤醒另一个因为wait()陷入Waiting状态的线程,然后调用wait(),释放monitor锁,另一个线程获取到锁,进行同样的操作,最终实现要求。