一道多线程题目的解决方案

发表于:2012-5-21 09:46

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:在程序的路上    来源:51Testing软件测试网采编

  在iteye上看到的一道多线程的题目,参考了一下网友的实现,那Eclipse调试通过,算是对JAVA5的并发库有个大致的了解,分享出来,欢迎园里的同学拍砖。

  题目:

  要求用三个线程,按顺序打印1,2,3,4,5.... 71,72,73,74, 75.

  线程1先打印1,2,3,4,5, 然后是线程2打印6,7,8,9,10, 然后是线程3打印11,12,13,14,15。接着再由线程1打印16,17,18,19,20....以此类推, 直到线程3打印到75。

  分析:感觉出题人是要考察一下你是否能够很好的控制多线程,让他们有序的进行。

  1、线程池:3个线程,需要使用并发库的线程池

  2、锁(lcok):在打印的时候,只允许一个线程进入,其他的线程等待

  下面的主要的代码:

  1. import java.util.HashMap;  
  2. import java.util.Map;  
  3. import java.util.concurrent.CountDownLatch;  
  4. import java.util.concurrent.ExecutorService;  
  5. import java.util.concurrent.Executors;  
  6. import java.util.concurrent.locks.Condition;  
  7. import java.util.concurrent.locks.Lock;  
  8. import java.util.concurrent.locks.ReentrantLock;  
  9. public class NumberPrinter {  
  10.     private Lock lock = new ReentrantLock();  
  11.     private Condition c1 = lock.newCondition();  
  12.     private Condition c2 = lock.newCondition();  
  13.     private Condition c3 = lock.newCondition();  
  14.     private Map<Integer, Condition> condtionContext =   
  15.         new HashMap<Integer, Condition>();  
  16.     public NumberPrinter() {  
  17.         condtionContext.put(Integer.valueOf(0), c1);  
  18.         condtionContext.put(Integer.valueOf(1), c2);  
  19.         condtionContext.put(Integer.valueOf(2), c3);  
  20.     }  
  21.       
  22.     private int count = 0;     
  23.       
  24.     public void print(int id) {  
  25.         lock.lock();  
  26.         try {  
  27.             while(count*5 < 75) {  
  28.                 int curID = calcID();  
  29.                 if (id == curID) {  
  30.                     for (int i = 1; i<=5; i++) {  
  31.                         System.out.print(count*5 +i+ ",");  
  32.                     }  
  33.                     System.out.println();  
  34.                     count++;  
  35.                     int nextID = calcID();  
  36.                     Condition nextCondition = condtionContext.get(  
  37.                             Integer.valueOf(nextID));  
  38.                     //通知下一线程 
  39.                     nextCondition.signal();  
  40.                 } else {  
  41.                     Condition condition = condtionContext.get(  
  42.                             Integer.valueOf(id));  
  43.                     condition.await();  
  44.                 }  
  45.             }  
  46.             //通知线程结束 
  47.             for(Condition c : condtionContext.values()) {  
  48.                 c.signal();  
  49.             }  
  50.         } catch (Exception e) {  
  51.             e.printStackTrace();  
  52.         } finally {  
  53.             lock.unlock();  
  54.         }  
  55.     }  
  56.       
  57.     private int calcID() {  
  58.         // TODO Auto-generated method stub 
  59.         return count % 3;  
  60.     }  
  61.     /** 
  62.      * @param args 
  63.      */ 
  64.     public static void main(String[] args) {  
  65.         ExecutorService executor = Executors.newFixedThreadPool(3);  
  66.         final CountDownLatch latch = new CountDownLatch(1);     
  67.         final NumberPrinter printer = new NumberPrinter();   
  68.         for (int i = 0; i < 3; i++) {     
  69.             final int id = i;  
  70.             executor.submit(new Runnable() {  
  71.                 @Override 
  72.                 public void run() {  
  73.                     // TODO Auto-generated method stub 
  74.                     try {  
  75.                         latch.await();  
  76.                     } catch (InterruptedException e) {  
  77.                         // TODO Auto-generated catch block 
  78.                         e.printStackTrace();  
  79.                     }  
  80.                     printer.print(id);  
  81.                 }  
  82.             });  
  83.         }  
  84.         System.out.println("三个任务开始顺序打印数字。。。。。。");   
  85.         latch.countDown();  
  86.         executor.shutdown();  
  87.     }  
  88. }

《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号