迅雷的多线程笔试题总结

原文:http://blog.csdn.net/qingfengliuquan/article/details/5891187

编写一个程序,开启3个线程,这3个线程的ID分别为A、B、C,每个线程将自己的ID在屏幕上打印10遍,要求输出结果必须按ABC的顺序显示;如:ABCABC….依次递推 这是一道迅雷的笔试题

总结下方法

1. 最佳的方法 用java.util.concurrent.Semaphore 信号量

[java]  view plain copy
  1. package quiz;  
  2.   
  3. import java.util.concurrent.Semaphore;  
  4.   
  5. public class SemaphoreABC {  
  6.       
  7.     static class T extends Thread{  
  8.           
  9.         Semaphore me;  
  10.         Semaphore next;  
  11.           
  12.         public T(String name,Semaphore me,Semaphore next){  
  13.             super(name);  
  14.             this.me = me;  
  15.             this.next = next;  
  16.         }  
  17.           
  18.         @Override  
  19.         public void run(){  
  20.             for(int i = 0 ; i < 10 ; i ++){  
  21.                 try {  
  22.                     me.acquire();  
  23.                 } catch (InterruptedException e) {  
  24.                     e.printStackTrace();  
  25.                 }  
  26.                 System.out.println(this.getName());  
  27.                 next.release();  
  28.             }  
  29.         }  
  30.     }  
  31.       
  32.     public static void main(String[] args) {  
  33.         Semaphore aSem = new Semaphore(1);  
  34.         Semaphore bSem = new Semaphore(0);  
  35.         Semaphore cSem = new Semaphore(0);  
  36.           
  37.         T a = new T("A",aSem,bSem);  
  38.         T b = new T("B",bSem,cSem);  
  39.         T c = new T("C",cSem,aSem);  
  40.           
  41.         a.start();  
  42.         b.start();  
  43.         c.start();  
  44.     }  
  45. }  

 

2. 用wait 和 notify 实现 同样借鉴了 信号量的思想,自己在上面的启发下改的

 

[java]  view plain copy
  1. package quiz;  
  2.   
  3. /** 
  4.  *  
  5.  *  
  6.  * <p> 
  7.  * Title: 迅雷笔试的测验 
  8.  * </p> 
  9.  * <p> 
  10.  * Description: 把abc 看做是三盏灯,循环亮,三个开关控制三个灯的,三个人代表三个线程 每次先看前一盏灯的亮灯的情况 
  11.  * 在看自己的情况,决定是否亮灯,然后将亮灯的消息通知给下个人 
  12.  * </p> 
  13.  * <p> 
  14.  * Copyright: Copyright (c) 2007-2010 
  15.  * </p> 
  16.  * <p> 
  17.  * Company: 
  18.  * </p> 
  19.  *  
  20.  * @author 
  21.  * @version 1.0 2010-9-17 
  22.  */  
  23. public class RunableThread1 implements java.lang.Runnable {  
  24.     // 内部开关类 isLighting=true 表示灯开  
  25.     private class Switch {  
  26.         public Switch(boolean printedSingal) {  
  27.             this.isLighting = printedSingal;  
  28.         }  
  29.   
  30.         public boolean isLighting;  
  31.     }  
  32.   
  33.     // a灯的开关  
  34.     Switch aSwitch = new Switch(false);  
  35.   
  36.     // b灯的开关  
  37.     Switch bSwitch = new Switch(false);  
  38.   
  39.     // c灯的开关 初始化 默认为开着,这样下次a灯才能亮  
  40.     Switch cSwitch = new Switch(true);  
  41.   
  42.     public void run() {  
  43.         // TODO Auto-generated method stub  
  44.   
  45.         for (int i = 0; i < 10; i++) {  
  46.             // 如果是A线程  
  47.             if (Thread.currentThread().getName().equals("A")) {  
  48.                 // 总是先去看前一盏灯的状态后,在决定是否轮到自己亮了  
  49.                 // A去申请控制等c灯的开关,如果此时c的开关空闲,A锁住开关,防止他人摆弄  
  50.                 synchronized (cSwitch) {  
  51.                     // 轮询上一盏灯c,如果c一直灭着,则等待,由于我们已经默认初始化c亮着  
  52.                     // 故不会死锁  
  53.                     while (!cSwitch.isLighting) {  
  54.                         try {  
  55.                             // 等着c亮的好消息  
  56.                             cSwitch.wait();  
  57.                         } catch (InterruptedException e) {  
  58.                             // TODO Auto-generated catch block  
  59.                             e.printStackTrace();  
  60.                         }  
  61.                     }  
  62.                     // c终于亮了,该哥a亮了 先打印出自己  
  63.                     System.out.print(Thread.currentThread().getName());  
  64.                     // 关掉c灯  
  65.                     cSwitch.isLighting = false;  
  66.                     // A去申请控制等a灯的开关,如果此时a的开关空闲,A锁住开关,防止他人摆弄  
  67.                     synchronized (aSwitch) {  
  68.                         // a灯亮了  
  69.                         aSwitch.isLighting = true;  
  70.                         // 将a灯亮的消息通知给B  
  71.                         aSwitch.notify();  
  72.                     }  
  73.   
  74.                 }  
  75.             } // B线程上场了,同上  
  76.             else if (Thread.currentThread().getName().equals("B")) {  
  77.                 synchronized (aSwitch) {  
  78.                     while (!aSwitch.isLighting) {  
  79.   
  80.                         try {  
  81.                             aSwitch.wait();  
  82.                         } catch (InterruptedException e) {  
  83.                             // TODO Auto-generated catch block  
  84.                             e.printStackTrace();  
  85.                         }  
  86.                     }  
  87.                     System.out.print(Thread.currentThread().getName());  
  88.                     aSwitch.isLighting = false;  
  89.                     synchronized (bSwitch) {  
  90.   
  91.                         bSwitch.isLighting = true;  
  92.                         bSwitch.notify();  
  93.                     }  
  94.   
  95.                 }  
  96.             } else if (Thread.currentThread().getName().equals("C")) {  
  97.   
  98.                 synchronized (bSwitch) {  
  99.                     while (!bSwitch.isLighting) {  
  100.                         try {  
  101.                             bSwitch.wait();  
  102.                         } catch (InterruptedException e) {  
  103.                             // TODO Auto-generated catch block  
  104.                             e.printStackTrace();  
  105.                         }  
  106.                     }  
  107.                     System.out.print(Thread.currentThread().getName());  
  108.                     bSwitch.isLighting = false;  
  109.                     synchronized (cSwitch) {  
  110.                         cSwitch.isLighting = true;  
  111.                         cSwitch.notify();  
  112.   
  113.                     }  
  114.                 }  
  115.             }  
  116.         }  
  117.     }  
  118.   
  119.     public static void main(String[] args) {  
  120.         RunableThread1 rt = new RunableThread1();  
  121.         Thread aThread = new Thread(rt, "A");  
  122.         Thread bThread = new Thread(rt, "B");  
  123.         Thread cThread = new Thread(rt, "C");  
  124.         aThread.start();  
  125.         bThread.start();  
  126.         cThread.start();  
  127.     }  
  128. }  

 

3. 同样用用wait 和 notify 实现 ,别人成果,自己加入了自己的理解

 

[java]  view plain copy
  1. package quiz;  
  2.   
  3. public class RunableThread2 implements java.lang.Runnable {  
  4.   
  5.     private class Switch {  
  6.         public Switch(boolean printedSingal) {  
  7.             this.isLighting = printedSingal;  
  8.         }  
  9.   
  10.         public boolean isLighting;  
  11.     }  
  12.   
  13.     Switch aSwitch = new Switch(false);  
  14.   
  15.     Switch bSwitch = new Switch(false);  
  16.   
  17.     Switch cSwitch = new Switch(false);  
  18.   
  19.     public void run() {  
  20.         // TODO Auto-generated method stub  
  21.   
  22.         for (int i = 0; i < 10; i++) {  
  23.             if (Thread.currentThread().getName().equals("A")) {  
  24.                 synchronized (cSwitch) {  
  25.   
  26.                     System.out.print(Thread.currentThread().getName());  
  27.                     synchronized (aSwitch) {  
  28.   
  29.                         aSwitch.isLighting = true;  
  30.   
  31.                         aSwitch.notify();  
  32.                     }  
  33.   
  34.                     while (!cSwitch.isLighting) {  
  35.                         try {  
  36.                             cSwitch.wait();  
  37.                         } catch (InterruptedException e) {  
  38.                             // TODO Auto-generated catch block  
  39.                             e.printStackTrace();  
  40.                         }  
  41.   
  42.                     }  
  43.   
  44.                     cSwitch.isLighting = false;  
  45.   
  46.                     //  
  47.   
  48.                 }  
  49.             } else if (Thread.currentThread().getName().equals("B")) {  
  50.                 synchronized (aSwitch) {  
  51.                     while (!aSwitch.isLighting) {  
  52.   
  53.                         try {  
  54.                             aSwitch.wait();  
  55.                         } catch (InterruptedException e) {  
  56.                             // TODO Auto-generated catch block  
  57.                             e.printStackTrace();  
  58.                         }  
  59.                     }  
  60.                     System.out.print(Thread.currentThread().getName());  
  61.                     aSwitch.isLighting = false;  
  62.                     synchronized (bSwitch) {  
  63.   
  64.                         bSwitch.isLighting = true;  
  65.                         bSwitch.notify();  
  66.                     }  
  67.   
  68.                 }  
  69.             } else if (Thread.currentThread().getName().equals("C")) {  
  70.   
  71.                 synchronized (bSwitch) {  
  72.                     while (!bSwitch.isLighting) {  
  73.                         try {  
  74.                             bSwitch.wait();  
  75.                         } catch (InterruptedException e) {  
  76.                             // TODO Auto-generated catch block  
  77.                             e.printStackTrace();  
  78.                         }  
  79.                     }  
  80.                     System.out.print(Thread.currentThread().getName());  
  81.                     bSwitch.isLighting = false;  
  82.                     synchronized (cSwitch) {  
  83.                         cSwitch.isLighting = true;  
  84.                         cSwitch.notify();  
  85.   
  86.                     }  
  87.                 }  
  88.             }  
  89.         }  
  90.     }  
  91.   
  92.     public static void main(String[] args) {  
  93.         RunableThread2 rt = new RunableThread2();  
  94.         Thread aThread = new Thread(rt, "A");  
  95.         Thread bThread = new Thread(rt, "B");  
  96.         Thread cThread = new Thread(rt, "C");  
  97.         aThread.start();  
  98.         bThread.start();  
  99.         cThread.start();  
  100.     }  
  101. }  

 

 

总结:

1.java 高级的concurrent包很强大,写复杂的控制很有用

2. 这个题目对理解wait 和notify 很有用,自己写了 才发现,看着是一回事 ,写又是另一回事情

3. 很多时候 特别要注意死锁,自己因为abc的打印 陷入了思路死锁很长时间,自己比较笨,呵呵,一定要给出初始化条件用来解除死锁(如程序2),或者条件判断避免死锁(如程序3),这个需要破除思维定势等。

4. 形象的思维很重要,synchronized (chair){} 想象为 某人去申请椅子,

如果椅子有人坐了,则阻塞自己,在while{里循环chair.wait()} ,直到有人通知 chair.notify() 你他要离开椅子,你方能去申请椅子

如果没人坐,先坐上,锁住椅子,防止别人坐,同时在椅子上做些事情,比如看书啥的,做完了,千万别忘了chair.notify() 别人。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值