zhangsan运行 : 0
sunny运行 : 0
sunny运行 : 1
sunny运行 : 2
zhangsan运行 : 1
zhangsan运行 : 2
zhangsan运行 : 3
sunny运行 : 3
zhangsan运行 : 4
sunny运行 : 4
注意:start()方法的调用后并不是立即执行多线程代码,而是使得该线程变为可运行态(Runnable),什么时候运行是由操作系统决定的;多线程程序是乱序执行。多个线程分别完成自己的任务。
2.2 实现Runnable
多个线程共同完成一个任务;不管是扩展Thread类还是实现Runnable接口来实现多线程,最终还是通过Thread的对象的API来控制线程的。
2.3 实现Callable
使用Callable+Future获取执行结果,并且可以抛出异常。
public class CallableDemo implements Callable<Integer> {
@Override
public Integer call() throws Exception {
int sum = 0;
System.out.println("Callable子线程开始计算啦!" + Thread.currentThread().getName());
Thread.sleep(2000);
for(int i=0 ;i<5000;i++){
sum=sum+i;
}
System.out.println("Callable子线程计算结束!" + Thread.currentThread().getName());
return sum;
}
}
Callable执行测试类如下:
public class CallableTest {
public static void main(String[] args) {
//创建线程池
ExecutorService es = Executors.newSingleThreadExecutor();
//创建Callable对象任务
CallableDemo calTask = new CallableDemo();
//提交任务并获取执行结果
Future<Integer> future = es.submit(calTask);
//关闭线程池
es.shutdown();
try {
Thread.sleep(2000);
System.out.println("主线程在执行其他任务");
if (future.get() != null) {
//输出获取到的结果
System.out.println("future.get()-->" + future.get());
} else {
//输出获取到的结果
System.out.println("future.get()未获取到结果");
}
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("主线程在执行完成");
}
}
2.4 总结
实现Runnable接口比继承Thread类所具有的优势:
1):适合多个相同的程序代码的线程去处理同一个资源
2):可以避免java中的单继承的限制
3):增加程序的健壮性,代码可以被多个线程共享,代码和数据独立
4):线程池只能放入实现Runable或callable类线程,不能直接放入继承Thread的类