近日在学习java的多线程编程,有一练习题:创建几个任务,它们各将睡眠一定时间,显示它们的睡眠时间并退出。
我刚开始写的代码是这样的:
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class sleepAWhile implements Runnable{
private static int taskCount=0;
private final int id =taskCount++;
private int time =0;
public sleepAWhile(int x){
this.time = x;
}
public void run() {
while(--time>0){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("this is the "+id+" times");
}
public static void main(String[] args) {
ExecutorService exec = Executors.newCachedThreadPool();
for(int i=0; i<5; i++){
long t1 = System.currentTimeMillis();
exec.execute(new sleepAWhile(i));
long t2 = System.currentTimeMillis();
System.out.println("time="+(t2-t1));
}
exec.shutdown();
}
}
最终执行的结果是:
time=0
this is the 0 times
time=0
this is the 1 times
time=0
time=0
time=0
this is the 2 times
this is the 3 times
this is the 4 times
可以看到,没有收集到各任务的睡眠时间,作为初学者的我对这一结果十分困惑,在同事帮助下才明白原来exec.execute(new sleepAWhile(i));这一句只是把线程放到线程池中,其后面的语句可以立即执行。
后来我将代码改成了这样:
package thinking650;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class sleepAWhile implements Runnable{
private static int taskCount=0;
private final int id =taskCount++;
private int time =0;
public sleepAWhile(int x){
this.time = x;
}
public void run() {
long t1 = System.currentTimeMillis();
while(--time>0){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
long t2 = System.currentTimeMillis();
System.out.println("time="+(t2-t1));
System.out.println("this is the "+id+" times");
}
public static void main(String[] args) {
ExecutorService exec = Executors.newCachedThreadPool();
for(int i=0; i<5; i++){
exec.execute(new sleepAWhile(i));
}
exec.shutdown();
}
}
结果如下:
time=0
this is the 0 times
time=0
this is the 1 times
time=1000
this is the 2 times
time=2001
this is the 3 times
time=3002
this is the 4 times
这就收集到了各个线程睡眠的时间。