多线程并发问题(二)

来源:互联网 发布:阿里文学作者收入知乎 编辑:程序博客网 时间:2024/06/07 04:06

  题目:现成程序中的Test类中的代码在不断地产生数据,然后交给TestDo.doSome()方法去处理,就好像生产者在不断地产生数据,消费者在不断消费数据。

       请将程序改造成有10个线程来消费生成者产生的数据,这些消费者都调用TestDo.doSome()方法去进行处理,故每个消费者都需要一秒才能处理完,程序应保证这些消费者线程依次有序地消费数据,只有上一个消费者消费完后,下一个消费者才能消费数据,下一个消费者是谁都可以,但要保证这些消费者线程拿到的数据是有顺序的。

【初始代码】

public class Test {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;}}


【解决方式】

package com.jjyy.customer;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;import java.util.concurrent.Semaphore;import java.util.concurrent.SynchronousQueue;/*Semaphore与SynchronousQueue的混合使用。由于Semaphore只有1个许可权,所以谁先拿到谁执行,然后释放,保证依次执行,用锁也行,只要保证一个线程执行即可SynchronousQueue是必须有其他线程取的动作,这样一一对应*/public class Test {public static void main(String[] args) {//定义一个许可权为1的信号灯[互斥信号量]final Semaphore semaphore = new Semaphore(1);//产生的结果无序final SynchronousQueue<String> queue = new SynchronousQueue<String>();ExecutorService executor = Executors.newFixedThreadPool(10);for (int i = 0; i < 10; i++) {executor.execute(new Runnable() {public void run() {try {semaphore.acquire();//获取许可String input = queue.take();//获取并移除此队列的头String output = TestDoIT.doSome(input);System.out.println(Thread.currentThread().getName()+ ":" + output);semaphore.release();//释放许可} catch (Exception e) {e.printStackTrace();}}});}System.out.println("begin:"+(System.currentTimeMillis()/1000));for(int i=0;i<10;i++){  //这行不能改动String input = i+"";  //这行不能改动try {queue.put(input);//将指定元素添加到此队列} catch (InterruptedException e) {e.printStackTrace();}}}}//不能改动此TestDo类class TestDoIT {public static String doSome(String input){try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}String output = input + ":"+ (System.currentTimeMillis() / 1000);return output;}}



0 0
原创粉丝点击