阿里的在线评测题:多线程打印数据

mac2024-01-29  36

我答的不好,那个伯乐在线评测系统不会用,本地写代码跑不成功挂了,总结下供后人参考。

  题目:

顺序递增打印正整数,从1开始打印到100,中间换行分隔。不允许重复打印出相同的数字,比如打印结果里出现2个5,3个6之类的。 要求如下: 1、使用三个线程A、B、C,其中线程A打印3的倍数,B打印5的倍数,C打印其他数字。

这个题目还是比较考察多线程功力的,因为常规的加锁、或者使用join、countdownlantch等我熟悉的已经失效了。我尝试了使用condition的wait,notify来3个线程互相唤醒。还是出现了加锁异常的情况:java.lang.IllegalMonitorStateException。从难度上来看,也比常见的两个线程交替打印奇、偶数要复杂。

       咨询了13哥。他的公众号:互联网架构师养成计划,可以看看。主要整理的干货不怎么挂上来,私聊就有。

13哥给出方案是使用信号量:Semaphore。我之前没有用过,给我的印象就是类似限流使用的,

常见的方法就是:

 semaphore.acquire();获取许可,

semaphore.release();释放许可。

抢不到的情况下会被hold.效率很高。有更好的结果也可以反馈下。

贴一下代码:

/** * * @author 13哥 * */ public class ShowSemaphore { //计数器 final static AtomicInteger count = new AtomicInteger(0); //信号量 static Semaphore sp3 = new Semaphore(1); static Semaphore sp5 = new Semaphore(1); static Semaphore other = new Semaphore(1); public static void main(String[] args) { Thread threadA =new Thread(new Runnable() { @Override public void run() { while(true) { int p = count.get(); if(p>100){ break; } if((p % 3 == 0) && (p % 5 != 0)) { sp3.acquireUninterruptibly(); System.out.println("threadA :" + p); count.getAndIncrement(); } sp5.release(); other.release(); } } }); Thread threadB =new Thread(new Runnable() { @Override public void run() { while(true) { int p = count.get(); if(p>100){ break; } if((p % 5 == 0) && (p % 3 != 0)) { sp5.acquireUninterruptibly(); System.out.println("threadB : " + p); count.getAndIncrement(); } sp3.release(); other.release(); } } }); Thread threadC =new Thread(new Runnable() { @Override public void run() { while(true) { int p = count.get(); if(p>100){ break; } if(((p % 5 != 0) && (p % 3 != 0)||(p % 15 == 0))) { other.acquireUninterruptibly(); System.out.println("threadc : " + p); count.getAndIncrement(); } sp3.release(); sp5.release(); } } }); threadA.start(); threadB.start(); threadC.start(); } }

输出结果:

threadc : 0 threadc : 1 threadc : 2 threadA :3 threadc : 4 threadB : 5 threadA :6 threadc : 7 threadc : 8 threadA :9 threadB : 10 threadc : 11 threadA :12 threadc : 13 threadc : 14 threadc : 15 threadc : 16 threadc : 17 threadA :18 threadc : 19 threadB : 20 threadA :21 threadc : 22 threadc : 23 threadA :24 threadB : 25 threadc : 26 threadA :27 threadc : 28 threadc : 29 threadc : 30 threadc : 31 threadc : 32 threadA :33 threadc : 34 threadB : 35 threadA :36 threadc : 37 threadc : 38 threadA :39 threadB : 40 threadc : 41 threadA :42 threadc : 43 threadc : 44 threadc : 45 threadc : 46 threadc : 47 threadA :48 threadc : 49 threadB : 50 threadA :51 threadc : 52 threadc : 53 threadA :54 threadB : 55 threadc : 56 threadA :57 threadc : 58 threadc : 59 threadc : 60 threadc : 61 threadc : 62 threadA :63 threadc : 64 threadB : 65 threadA :66 threadc : 67 threadc : 68 threadA :69 threadB : 70 threadc : 71 threadA :72 threadc : 73 threadc : 74 threadc : 75 threadc : 76 threadc : 77 threadA :78 threadc : 79 threadB : 80 threadA :81 threadc : 82 threadc : 83 threadA :84 threadB : 85 threadc : 86 threadA :87 threadc : 88 threadc : 89 threadc : 90 threadc : 91 threadc : 92 threadA :93 threadc : 94 threadB : 95 threadA :96 threadc : 97 threadc : 98 threadA :99 threadB : 100

还有个是常规日志输出的题目,不贴了。

常规的读文件,一行行的处理,截取URL,统计应该还OK。

要是日志很大,而且URL复杂(需要考虑放到内存处理比如map会爆掉的情况)

最新回复(0)