- 现有的程序代码模拟产生16个日志对象,并且需要运行16秒才能打印完这些日志,请在程序中增加4个线程,使4秒执行完。
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
public class TestMianshiTi {
public static void main(String[] args) {
System.out.println("begin:"+(System.currentTimeMillis()/1000));
/*
* 模拟处理16行日志,下面的代码产生了16个日志对象,当前代码需要运行16秒才能打印完
* 修改程序代码,开四个线程让这16个对象在4秒钟打完
*/
for (int i = 0; i < 16; i++) { //这行代码不能动
final String log = "" + (i+1); //这行代码不能动
{
TestMianshiTi.parselog(log);
}
}
}
public static void parselog(String log) {
System.out.println(log + (System.currentTimeMillis()/1000));
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
现程序中的Test类中的代码不断产生数据,然后交给TestDo.doSome()方法处理, 就好像生产者在不断地生产数据,消费者不断消费数据。请将程序改造成10个线程来消费生产者的数据,这些消费者都调用TestDo.doSome()方法去进行处理,故每个消费者都需要一秒才能处理完,程序应保证这些消费者线程依次有序地消费数据,只有上一个消费者消费完后,下一个消费者才能消费数据,下一个消费者是谁都可以,但要保证这些消费者线程拿到的数据是由顺序的。原始代码如下
public class Test2 {
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);
}
}
}
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 Test2 {
public static void main(String[] args) {
System.out.println("begin:"+ System.currentTimeMillis()/1000);
SynchronousQueue<String> queue = new SynchronousQueue<>();
Semaphore semaphore = new Semaphore(1);
for (int i = 0; i < 10; i++) { //这行不能改动
new Thread(()-> {
try {
semaphore.acquire(); //不加这个则10个输出同时打印
String input = queue.take();
String output = TestDo.doSome(input);
System.out.println(Thread.currentThread().getName() + " | " + output);
semaphore.release(); //不加这个则10个输出同时打印
} catch (InterruptedException e) {
e.printStackTrace();
}
}).start();
}
for (int i = 0; i < 10; i++) { //这行不能改动
String input = i + ""; //这行不能改动
try {
queue.put(input);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
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;
}
}
现有程序同时启动了4个线程去调用TestDo.doSome(key,value)方法,由于TestDo.doSome(key,value)方法内的代码是先暂停1秒,然后再输出以秒为单位的当前时间值,所以,会打印出4个相同的时间值,如下所示:
4:4:1258199615
1:1:1258199615
3:3:1258199615
1:2:1258199615
请修改代码,如果有几个线程调用TestDo.doSome(key,value)方法时传进去的key相等(equals比较为true)则这几个线程应互斥排队输出结果,即当有2个线程key都是“1”时,他们中的一个要比另外一个其他线程晚1秒输出结果,如下所示:
4:4:1258199615
1:1:1258199615
3:3:1258199615
1:2:1258199616