题目如下:现成程序中的Test类中的代码在不断的产生数据,然后交给TestDo.doSome()方法去处理,就好像生产者在不断的产生数据,消费者在不断的消费数据。请将程序改造成有10个线程来消费生产者产生的数据,这些消费者都调用TestDo.doSome()方法去进行处理,故每个消费者都需要1秒钟才能处理完,程序应保证这些消费者线程依次有序消费数据,只有上一个消费者消费完后,下一个消费者才能消费数据,下一个消费者是谁都可以,但要保证这些消费者线程拿到的数据的数据是有顺序的(比如拿出的数据是1,2,3,4,5,6,7,8,9,但是谁拿1无所谓)。
- 为改动前单线程处理的例子
- public class Test1 {
- public static void main(String[] args) {
- System.out.println("begin :"+(System.currentTimeMillis()/1000));
- for (int i = 0; i < 10; i++) {//这行不能改动
- String input=i+"";//这行不能改动
- String output = TestDo.doSome(input);
- System.out.println(Thread.currentThread().getName()+":"+output);
- }
- }
- }
- //不能改动TestDo类
- class TestDo{
- public static String doSome(String input){
- try {
- Thread.sleep(1000);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- String output=input+":"+(System.currentTimeMillis()/1000);
- return output;
- }
- }
上面的代码是一个main线程来“取”10条数据的,程序运行的结果如下:
下面的代码是改为用10个线程来取这10个数据,注意取出的数据是有序的
- 1-2 一个10线程取数据,取出的数据是有序的例子
- import java.util.concurrent.Semaphore;
- import java.util.concurrent.SynchronousQueue;
- public class Test {
- public static void main(String[] args) {
- final Semaphore semaphore = new Semaphore(1);
- final SynchronousQueue<String> queue = new SynchronousQueue<String>();
- for(int i=0;i<10;i++){//创建10个线程“消费者”
- new Thread(new Runnable(){
- @Override
- public void run() {
- try {
- semaphore.acquire();//拿到信号灯
- String input = queue.take();//取数据
- String output = TestDo.doSome(input);//"处理数据"
- System.out.println(Thread.currentThread().getName()+ ":" + output);
- semaphore.release();//还回信号灯
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- }).start();
- }
- System.out.println("begin:"+(System.currentTimeMillis()/1000));
- for(int i=0;i<10;i++){ //这行不能改动,有10个数据
- String input = i+""; //这行不能改动
- try {
- queue.put(input);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- }
- }
- //不能改动此TestDo类
- class TestDo {
- public static String doSome(String input){
- try {
- Thread.sleep(1000);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- String output = input + ":"+ (System.currentTimeMillis() / 1000);
- return output;
- }
- }
程序运行的效果如下:
可以看到10个线程取出的数据“1,2,3...9”是有序的,但是那一个线程先取无所谓。
转载于:https://blog.51cto.com/020618/1187155