公告:“业余草”微信公众号提供免费CSDN下载服务(只下Java资源),关注业余草微信公众号,添加作者微信:xttblog2,发送下载链接帮助你免费下载!
本博客日IP超过2000,PV 3000 左右,急需赞助商。
极客时间所有课程通过我的二维码购买后返现24元微信红包,请加博主新的微信号:xttblog2,之前的微信号好友位已满,备注:返现
受密码保护的文章请关注“业余草”公众号,回复关键字“0”获得密码
所有面试题(java、前端、数据库、springboot等)一网打尽,请关注文末小程序
腾讯云】1核2G5M轻量应用服务器50元首年,高性价比,助您轻松上云
本博客日IP超过2000,PV 3000 左右,急需赞助商。
极客时间所有课程通过我的二维码购买后返现24元微信红包,请加博主新的微信号:xttblog2,之前的微信号好友位已满,备注:返现
受密码保护的文章请关注“业余草”公众号,回复关键字“0”获得密码
所有面试题(java、前端、数据库、springboot等)一网打尽,请关注文末小程序
腾讯云】1核2G5M轻量应用服务器50元首年,高性价比,助您轻松上云
很多人都想进 BAT,但是并不是每个人都能如愿。BAT 的面试非常的严格,今年春招,阿里的一道线程面试题,就淘汰了无数的人!
今天我对这道题,分别用了 3 种不同的方法实现了,供大家参考!
题目如下:
通过N个线程顺序循环打印从0至100,如给定N=3则输出:
thread0: 0
thread1: 1
thread2: 2
thread0: 3
thread1: 4
…..
第一种,通过判断执行状态来实现。
static int result = 0; public static void orderPrintNum(final int n){ final boolean [] printFlag = new boolean [n]; for (int i = 0; i < n; i++) { final int index = i; if(0 == i){ printFlag[index] = true; } new Thread(new Runnable() { public void run() { try { while (result <= 100) { if(printFlag[index]){ System.out.println("thread" + index + ": " + result++); printFlag[index] = false; if(index == (n - 1)){ printFlag[0] = true; }else { printFlag[index + 1] = true; } } } } catch (Exception e) { e.printStackTrace(); } } }).start(); } }
想到这种方式的,应该就能想到信号量。因此,第二种实现方法就是通过信号量来实现。
static int result = 0; public static void orderPrintNum2(final int n) throws InterruptedException{ // N 个线程 Thread [] threads = new Thread[n]; // N 个Semaphore final Semaphore[] syncSemaphore = new Semaphore[n]; for (int i = 0; i < n; i++) { //非公平信号量,计数为1 syncSemaphore[i] = new Semaphore(1); if (i != n-1){ //获取一个许可前线程将一直阻塞 syncSemaphore[i].acquire(); } } for (int i = 0; i < n; i++) { final Semaphore lastSemphore = i == 0 ? syncSemaphore[n - 1] : syncSemaphore[i - 1]; final Semaphore curSemphore = syncSemaphore[i]; final int index = i; threads[i] = new Thread(new Runnable() { public void run() { try { while (true) { lastSemphore.acquire(); System.out.println("thread" + index + ": " + result++); if (result > 100){ System.exit(0); } curSemphore.release(); } } catch (Exception e) { e.printStackTrace(); } } }); threads[i].start(); } }
第三种,通过 wait 和 notifyAll 来实现。
static int result = 0; public static void orderPrintNum3(final int n) { final Object LOCK = new Object(); final int [] flag = new int[1]; for (int i = 0;i < n; i++){ final int index = i; new Thread(new Runnable() { public void run() { try { while (result <= 100) { synchronized (LOCK){ if(flag[0] == index){ System.out.println("thread" + index + ": " + result++); flag[0] = index == n - 1 ? 0 : index + 1; // 唤醒其他wait线程 LOCK.notifyAll(); }else { LOCK.wait(); } } } } catch (Exception e) { e.printStackTrace(); } } }).start(); } }
3 种方法的运行效果,截图如下:
除此之外,还可以通过队列,链表等形式来实现。具体,大家去思考思考吧!
最后,欢迎关注我的个人微信公众号:业余草(yyucao)!可加作者微信号:xttblog2。备注:“1”,添加博主微信拉你进微信群。备注错误不会同意好友申请。再次感谢您的关注!后续有精彩内容会第一时间发给您!原创文章投稿请发送至532009913@qq.com邮箱。商务合作也可添加作者微信进行联系!
本文原文出处:业余草: » 阿里的一道线程面试题,面哭了无数人