题目如下:现成程序中的Test类中的代码在不断的产生数据,然后交给TestDo.doSome()方法去处理,就好像生产者在不断的产生数据,消费者在不断的消费数据。请将程序改造成有10个线程来消费生产者产生的数据,这些消费者都调用TestDo.doSome()方法去进行处理,故每个消费者都需要1秒钟才能处理完,程序应保证这些消费者线程依次有序消费数据,只有上一个消费者消费完后,下一个消费者才能消费数据,下一个消费者是谁都可以,但要保证这些消费者线程拿到的数据的数据是有顺序的(比如拿出的数据是1,2,3,4,5,6,7,8,9,但是谁拿1无所谓)。

  • 为改动前单线程处理的例子
 
  
  1. public class Test1 { 
  2.     public static void main(String[] args) { 
  3.         System.out.println("begin :"+(System.currentTimeMillis()/1000)); 
  4.         for (int i = 0; i < 10; i++) {//这行不能改动 
  5.             String input=i+"";//这行不能改动 
  6.             String output = TestDo.doSome(input); 
  7.             System.out.println(Thread.currentThread().getName()+":"+output); 
  8.         } 
  9.     } 
  10.  
  11. //不能改动TestDo类 
  12. class TestDo{ 
  13.     public static String doSome(String input){ 
  14.         try { 
  15.             Thread.sleep(1000); 
  16.         } catch (InterruptedException e) { 
  17.             e.printStackTrace(); 
  18.         } 
  19.         String output=input+":"+(System.currentTimeMillis()/1000); 
  20.         return output; 
  21.     }  

上面的代码是一个main线程来“取”10条数据的,程序运行的结果如下:

下面的代码是改为用10个线程来取这10个数据,注意取出的数据是有序的

  • 1-2 一个10线程取数据,取出的数据是有序的例子
 
  
  1. import java.util.concurrent.Semaphore; 
  2. import java.util.concurrent.SynchronousQueue; 
  3.  
  4. public class Test { 
  5.     public static void main(String[] args) { 
  6.         final Semaphore semaphore = new Semaphore(1); 
  7.         final SynchronousQueue<String> queue = new SynchronousQueue<String>(); 
  8.         for(int i=0;i<10;i++){//创建10个线程“消费者” 
  9.             new Thread(new Runnable(){ 
  10.                 @Override 
  11.                 public void run() {  
  12.                     try { 
  13.                         semaphore.acquire();//拿到信号灯 
  14.                         String input = queue.take();//取数据 
  15.                         String output = TestDo.doSome(input);//"处理数据" 
  16.                         System.out.println(Thread.currentThread().getName()+ ":" + output); 
  17.                         semaphore.release();//还回信号灯 
  18.                     } catch (InterruptedException e) { 
  19.                         e.printStackTrace(); 
  20.                     }    
  21.                 } 
  22.             }).start(); 
  23.         } 
  24.          
  25.         System.out.println("begin:"+(System.currentTimeMillis()/1000)); 
  26.         for(int i=0;i<10;i++){  //这行不能改动,有10个数据 
  27.             String input = i+"";  //这行不能改动 
  28.             try { 
  29.                 queue.put(input); 
  30.             } catch (InterruptedException e) { 
  31.                 e.printStackTrace(); 
  32.             } 
  33.         } 
  34.     } 
  35.  
  36. //不能改动此TestDo类 
  37. class TestDo { 
  38.     public static String doSome(String input){ 
  39.         try { 
  40.             Thread.sleep(1000); 
  41.         } catch (InterruptedException e) { 
  42.             e.printStackTrace(); 
  43.         } 
  44.         String output = input + ":"+ (System.currentTimeMillis() / 1000); 
  45.         return output; 
  46.     } 

程序运行的效果如下:

可以看到10个线程取出的数据“1,2,3...9”是有序的,但是那一个线程先取无所谓。