首页 > 代码库 > 关于线程的一到面试题
关于线程的一到面试题
节录于<<张孝祥-Java多线程与并发库高级应用>>
题目概述
主线程执行10次 然后子线程执行5次 接着主线程再执行10次 子线程执行5次....一直循环50次。首先我们应该明白我们的线程逻辑在于
"主线程执行10次 然后子线程执行5次"
至于循环50次不是我们最核心的业务逻辑。
因而我们先把"主线程执行10次 然后子线程执行5次"放到一个类中。
第一步
class Business{ public void main(int j){ //j作为最大的那个50次循环 for(int i=1;i<=10;i++) System.out.println("main "+i+" of loop "+j); } public void sub(int j){ //j作为最大的那个50次循环 for(int i=1;i<=5;i++) System.out.println("sub "+i+" of loop "+j); } }然后就简单了,我们做出调用的类
public class TraditionalCommunication{ public static void main(String[] args){ final Business b=new Business(); new Thread( new Runnable(){ public void run(){ for(int i=1;i<=50;i++) b.sub(i); } } ).start(); for(int i=1;i<=50;i++) b.main(i); } }
如果就是现在这个代码去运行。看到的结果肯定是杂乱无章的。
可能父线程刚走了一圈(输出了一行代码),子线程就抢过了执行权。
第二步
所以只是我们得给business的两个方法,main与sub加上synchronized。这个时候再测试,最起码两个线程(父线程子线程)不会互相干扰(互斥),但是还有可能父线程接连着运行了两圈(输出了20行代码)也就是说,我们让两个线程能互斥,但是不能协调的通信。(他们没有交替输出!)
第三步
class Business{ private boolean shouldsub=true; //这个变量名 起的很不错 public synchronized void main(int j){ //j作为最大的那个50次循环 if(shouldsub){ try{ this.wait(); }catch(Exception e){ } } for(int i=1;i<=10;i++) System.out.println("main "+i+" of loop "+j); shouldsub=true; //父线程已经执行了一次 所以shouldsub为true 该子线程执行了 this.notify(); } public synchronized void sub(int j){ //j作为最大的那个50次循环 if(!shouldsub){ try{ this.wait(); }catch(Exception e){ } } for(int i=1;i<=5;i++) System.out.println("sub "+i+" of loop "+j); shouldsub=false; //子线程已经执行了一次 所以shouldsub为false 不能再执行了 this.notify(); } }
这下OK了。大家看看还有可以修改的地方么?
if(!shouldsub){ try{ this.wait(); }catch(Exception e){ } } 应该改成下面的形式 while(!shouldsub){ try{ this.wait(); }catch(Exception e){} }
为什么?
因为有的时候线程会被"假唤醒",用while循环可以再判断一回。
其实写完代码,我仍然觉得这个题的关键就是把business类抽象出来,提炼出真正核心的业务逻辑。
关于线程的一到面试题
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。