我答的不好,那个伯乐在线评测系统不会用,本地写代码跑不成功挂了,总结下供后人参考。
题目:
顺序递增打印正整数,从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会爆掉的情况)