多线程的学习
1、Callable和runnable区别:
class c implements Callable<String>{
@Override
public String call() throws Exception {
return null;
}
}
class r implements Runnable{
@Override
public void run() {
}
}
相同点:
1、两者都是接口
2、两者都需要调用Thread.start启动线程
不同点:
1、如上面代码所示,callable的核心是call方法,允许返回值,runnable的核心是run方法,没有返回值
2、call方法可以抛出异常,但是run方法不行
3、因为runnable是java1.1就有了,所以他不存在返回值,后期在java1.5进行了优化,就出现了callable,就有了返回值和抛异常
4、callable和runnable都可以应用于executors。而thread类只支持runnable
5、Callable只能用线程池来启动
测试:使用线程池来运行
public static void main(String[] args) throws Exception{
//1 创建一个线程池
//调用Executors类的静态方法
ExecutorService service = Executors.newFixedThreadPool(10);
//2提交runnable对象
service.submit(new Runnable() {
@Override
public void run() {
}
});
//3 提交callable对象
service.submit(new Callable<String>() {
@Override
public String call() throws Exception {
return null;
}
});
//4 关闭线程池
service.shutdown();
}
使用Thread来创建一个Callable,调用
Tread的构造方法中没有Tread(Callable callable)方法,所以需要一个既和Runable有关系,又与Callable有关系的类,FutureTask类。
FutureTask实现了Runable接口,并且其构造方法可以传递Callable
public static void main(String[] args) throws Exception{
// callable用thread调用需要一个FutureTask中间类
Runnable target;
Callable<String> callable = new Callable<String>() {
@Override
public String call() throws Exception {
return null;
}
};
FutureTask futureTask = new FutureTask<>(callable);
Thread thread = new Thread(futureTask);
thread.start();
// 获取返回值
Object o = futureTask.get();
}
做个简单的小测试:
- 有4个同学,1同学计算1+2+3+4,2同学计算1+2+…+10000,3同学计算20+21+22,4同学计算100+200+300。
- 这时同学2的计算量比较大,FutureTask单开启线程给2同学计算,先汇总1,3,4同学的计算数据,等2同学完成后再调用get汇总全部。
public static void main(String[] args) throws ExecutionException, InterruptedException {
FutureTask futureTask = new FutureTask(new Callable<Integer>() {
@Override
public Integer call() throws Exception {
System.out.println(Thread.currentThread().getName()+System.currentTimeMillis()+"进入了callable中");
int result = 0;
for (int i = 0 ;i<10001;i++){
result += i;
}
System.out.println(Thread.currentThread().getName()+System.currentTimeMillis()+"结束");
return result;
}
});
Thread thread = new Thread(futureTask);
thread.start();
System.out.println("第二位同学的计算值:"+futureTask.get());
int a = 1+2+3+4;
int b = 20+21+22;
int c = 100+200+300;
int all = a+b+c+(int)futureTask.get();
System.out.println("所有的计算值:"+all);
}