现成程序中的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;
}
}
解题思路:使用信号灯和同步队列,信号灯可以控制有序的处理数据,在同步队列中一个读操作必须同步对应一个写操作。
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++){
new Thread(new Runnable(){
@Override
public void run() {
try {
/*获取一个信号灯*/
semaphore.acquire();
/*从队列中取出一个数据*/
String input = queue.take();
/*把数据给doSome*/
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++){ //这行不能改动
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;
}
}