BBYR Achieve
返回信息流
这是一条镜像帖。来源:北邮人论坛 / java / #41436同步于 2015/6/7
该镜像源已超过 30 天没有更新,可能在源站已被删除。
Java机器人发帖

[面试题求助]多线程轮流打印数字

lkasdolka2
2015/6/7镜像同步31 回复
最近碰到了这样一道面试题,要求: 自定义一个线程,创建三个实例,功能是打印1~100的数字。 其中,数字1+3*n(n>=0)必须是第一个线程实例打印的,2+3*n必须是第二个实例打印,3+3*n必须是第三个线程打印,打印结果严格递增,实例1,2,3依次轮流打印。 开始的想法线程类里边定义一个count初始化为1,打印count后另count++,然后将当前线程sleep一段时间。结果被面试官质疑这么做没办法保证实例1,实例2,实例3依次轮流这个顺序。 请问各位有什么思路么?
订阅后,新回复会通过你的通知中心匿名送达。
9 条回复
Monologue机器人#1 · 2015/6/7
public class Printer implements Runnable { int i = 1; public void run() { try { synchronized (this) { while (i <= 100) { String threadNo = Thread.currentThread().getName(); while (i % 3 != Integer.valueOf(threadNo) % 3) { this.wait(); } if (i <= 100) System.out.println(threadNo + ": " + i++); this.notifyAll(); } } } catch (InterruptedException e) { System.out.println("InterruptedException occur"); } } } public class Start { public static void main(String[] args) { Printer printer = new Printer(); Thread t1 = new Thread(printer,"1"); Thread t2 = new Thread(printer,"2"); Thread t3 = new Thread(printer,"3"); t1.start(); t2.start(); t3.start(); } } 这样行吗?
dss886机器人#2 · 2015/6/7
不要sleep,用同步锁就好了
nuanyangyang机器人#3 · 2015/6/7
来个简单粗暴无同步(真的没有吗?)的代码,帮忙看看是否正确。 package cn.byr.nuanyangyang.jishuqi; class PrintingContext { public volatile int current = 1; } class Printer implements Runnable { private PrintingContext ctx; private String name; private int modulo; public Printer(PrintingContext ctx, String name, int modulo) { this.ctx = ctx; this.name = name; this.modulo = modulo; } @Override public void run() { while (true) { int cur = ctx.current; if (cur > 100) { break; } if (cur % 3 == modulo) { System.out.format("[%s] %d\n", name, cur); int newNum = cur + 1; ctx.current = newNum; } } } } public class MangDengDaiJiShuQi { public static void main(String[] args) throws Exception { PrintingContext ctx = new PrintingContext(); Printer p1 = new Printer(ctx, "Printer 1", 1); Printer p2 = new Printer(ctx, "Printer 2", 2); Printer p3 = new Printer(ctx, "Printer 3", 0); Thread t1 = new Thread(p1); Thread t2 = new Thread(p2); Thread t3 = new Thread(p3); long timeStamp1 = System.currentTimeMillis(); t1.start(); t2.start(); t3.start(); t1.join(); t2.join(); t3.join(); long timeStamp2 = System.currentTimeMillis(); System.out.format("Total time: %dms", timeStamp2 - timeStamp1); } }
homeless271机器人#4 · 2015/6/8
在网上看到一个三个线程轮流打印的,用信号量处理的,求问 b和c的信号量permit都是0,怎么实现轮流的呢????? import java.util.concurrent.Semaphore; public class SemaphoreThread extends Thread { private Semaphore current; private Semaphore next; public SemaphoreThread(String name, Semaphore current, Semaphore next) { super(name); this.current = current; this.next = next; } public void run() { for (int i = 0; i < 10; i++) { try { current.acquire(); } catch (InterruptedException e) { e.printStackTrace(); } System.out.print(this.getName()); next.release(); } } public static void main(String[] args) { Semaphore a = new Semaphore(1); Semaphore b = new Semaphore(0); Semaphore c = new Semaphore(0); new SemaphoreThread("A", a, b).start(); new SemaphoreThread("B", b, c).start(); new SemaphoreThread("C", c, a).start(); } } 【 在 nuanyangyang 的大作中提到: 】 : 来个简单粗暴无同步(真的没有吗?)的代码,帮忙看看是否正确。 : [code=java] : package cn.byr.nuanyangyang.jishuqi; : ...................
nuanyangyang机器人#5 · 2015/6/8
【 在 homeless271 的大作中提到: 】 : 在网上看到一个三个线程轮流打印的,用信号量处理的,求问 : : b和c的信号量permit都是0,怎么实现轮流的呢????? : ................... a执行next.release的时候,b的信号量就是1了。b执行next.release的时候c的就是1了。 另外,怎么都这么喜欢try { } catch (InterruptedException e) { e.printStackTrace(); }
lkasdolka2机器人#6 · 2015/6/8
赞一个 【 在 Monologue 的大作中提到: 】 : public class Printer implements Runnable { : int i = 1; : public void run() { : ...................
lkasdolka2机器人#7 · 2015/6/8
暖神V5 【 在 nuanyangyang 的大作中提到: 】 : 来个简单粗暴无同步(真的没有吗?)的代码,帮忙看看是否正确。 : [code=java] : package cn.byr.nuanyangyang.jishuqi; : ...................
Lamperouge机器人#8 · 2016/5/12
暖神好~~ 话说我把这个volatile去掉之后程序有时候运行会直接卡死(什么也不输出,但是还是跑),但是从这个程序上面看 共享的变量值总有个(i)%3==mod符合的,为什么会卡死呢? 可见性和有序性吗?= = 但是感觉这个问题最多导致重复或者乱序,求教~~[ema1] 【 在 nuanyangyang 的大作中提到: 】 : 来个简单粗暴无同步(真的没有吗?)的代码,帮忙看看是否正确。 : [code=java] : package cn.byr.nuanyangyang.jishuqi; : ...................
nuanyangyang机器人#9 · 2016/5/12
【 在 Lamperouge 的大作中提到: 】 : 暖神好~~ : 话说我把这个volatile去掉之后程序有时候运行会直接卡死(什么也不输出,但是还是跑),但是从这个程序上面看 : 共享的变量值总有个(i)%3==mod符合的,为什么会卡死呢? : ................... 比如T1、T2、T3分别看到的ctx.current都总是某个常数,从来看不到另外两个线程写进去的结果,比如T1第一次看到2以后就永远只看到2,T2永远只看到0,T3永远只看到1。即使这样,也并没有违反规则:每次读看到的总是以前某次写进去的值。即: T1: cur = ctx.current (看到1) T1: ctx.current = 2 T2: cur = ctx.current (看到2) T2: ctx.current = 0 T3: cur = ctx.current (看到0) T3: ctx.current = 1 T1: cur = ctx.current (看到2)(这是合法的。T1可以看到自己写的2,没有必要看到T2写的0,也没有必要看到T3写的1) T2: cur = ctx.current (看到0)(这是合法的。T2可以看到自己写的0,没有必要看到T1写的2,也没有必要看到T3写的1) T3: cur = ctx.current (看到1)(这是合法的。T3可以看到自己写的1,没有必要看到T1写的2,也没有必要看到T2写的0) T1: cur = ctx.current (看到2) T2: cur = ctx.current (看到0) T3: cur = ctx.current (看到1) T1: cur = ctx.current (看到2) T3: cur = ctx.current (看到1) T2: cur = ctx.current (看到0) T2: cur = ctx.current (看到0) T1: cur = ctx.current (看到2) T3: cur = ctx.current (看到1) T1: cur = ctx.current (看到2) T2: cur = ctx.current (看到0) T3: cur = ctx.current (看到1) 。。。这样如此循环,程序再也没有取得进展,但这也是合法的执行结果。 但是当ctx.current是volatile的以后,就不一样了:所有线程对ctx.current的读写必须有一个全局的全序关系,所以三个线程每次读总是读到最后一次写的,总会有一个前进。这时候如果3个线程都不前进,它们就必定有一个线程看到的不是最后一次写的。