java计算所有子线程结果_获取子线程的结果

1.大纲

Runnable的不足

CallAble的接口

Future类

一:Runnable的不足

1.不足

不能返回返回值

run方法不能抛出异常,因为大部分可以处理异常的不是我们写的,所以,要想处理,还是要在run里进行自己处理异常

2.程序

@FunctionalInterface

public interface Runnable {

/**

* When an object implementing interface Runnable is used

* to create a thread, starting the thread causes the object's

* run method to be called in that separately executing

* thread.

*

* The general contract of the method run is that it may

* take any action whatsoever.

*

* @see java.lang.Thread#run()

*/

public abstract void run();

}

二:CallAble接口

1.说明

实现call

2.程序

@FunctionalInterface

public interface Callable {

/**

* Computes a result, or throws an exception if unable to do so.

*

* @return computed result

* @throws Exception if unable to compute a result

*/

V call() throws Exception;

}

三:Future

1.作用

不要要等待,需要的时候,到future获取数据

2.Callable与Future的关系

可以使用Future.get来获取Callable接口返回的执行结果

可以通过Future.isDone来判断任务是否已经执行完成,

如果call()还没有执行完成,调用get的线程将会被阻塞,只有等运行完成,才能获取到结果,然后主线程才回切换到runnable的状态

3.总结

Future是一个存储器,存储了call这个任务的结果

4.主要方法

439073c4d8b78fb8fc28143b410c142d.png

5.get方法

V get() throws InterruptedException, ExecutionException;

9587be7f85acf4b5f8e608113d114d22.png

e553307e3bf1c5b4550343a4b25bb77c.png

6.get(timeout,unit)

V get(long timeout, TimeUnit unit)

超时很常见

超时不获取,任务需要取消

7.cancel方法

boolean cancel(boolean mayInterruptIfRunning);

8.isDone

boolean isDone();

是否完毕,不一定是成功的,抛出异常也是执行完毕

9.isCancel

boolean isCancelled();

四:代码演示

1.基础的用法

线程池的submit方法返回Future对象

a42fd64945e4e8e64230d7ce860e0998.png

public class OneFuture {

public static void main(String[] args) {

ExecutorService executorService = Executors.newFixedThreadPool(10);

Future future = executorService.submit(new CallableTask());

try {

System.out.println(future.get());

} catch (InterruptedException e) {

e.printStackTrace();

} catch (ExecutionException e) {

e.printStackTrace();

}

executorService.shutdown();

}

static class CallableTask implements Callable{

@Override

public Integer call() throws Exception {

Thread.sleep(3000);

return new Random(10).nextInt();

}

}

}

效果:

Connected to the target VM, address: '127.0.0.1:49767', transport: 'socket'

-1157793070

Disconnected from the target VM, address: '127.0.0.1:49767', transport: 'socket'

Process finished with exit code 0

2.lambda方式

public class TwoFuture {

public static void main(String[] args) {

ExecutorService executorService = Executors.newFixedThreadPool(10);

Callable callable = ()->{

Thread.sleep(3000);

return new Random(10).nextInt();

};

Future future = executorService.submit(callable);

try {

System.out.println(future.get());

} catch (InterruptedException e) {

e.printStackTrace();

} catch (ExecutionException e) {

e.printStackTrace();

}

executorService.shutdown();

}

}

3.多个任务,使用Future数组来获取结果

package com.jun.juc.feature;

import java.util.ArrayList;

import java.util.Random;

import java.util.concurrent.*;

public class ThreeFuture {

public static void main(String[] args) {

ExecutorService executorService = Executors.newFixedThreadPool(2);

Callable callable = ()->{

Thread.sleep(3000);

return new Random(10).nextInt();

};

ArrayList futures = new ArrayList<>();

for(int i=0;i<20;i++){

Future future = executorService.submit(callable);

futures.add(future);

}

//

for(int i=0;i<20;i++){

Future future = futures.get(i);

try {

Integer integer = future.get();

System.out.println(integer);

} catch (InterruptedException e) {

e.printStackTrace();

} catch (ExecutionException e) {

e.printStackTrace();

}

}

}

}

结果:

可以发现,每次是两个结果返回。因为线程池中才两个线程。

4.任务执行过程中抛出异常

package com.jun.juc.feature;

import java.util.Random;

import java.util.concurrent.*;

public class FourFuture {

public static void main(String[] args) {

ExecutorService executorService = Executors.newFixedThreadPool(10);

Callable callable = ()->{

throw new IllegalArgumentException("callable异常");

};

Future future = executorService.submit(callable);

try {

Thread.sleep(5000);

future.get();

} catch (InterruptedException e) {

e.printStackTrace();

System.out.println("InterruptedException异常了");

} catch (ExecutionException e) {

e.printStackTrace();

System.out.println("ExecutionException异常了");

}

executorService.shutdown();

}

}

只有在get的时候,才会抛出异常,而且异常是ExecutionException

5.获取任务超时

package com.jun.juc.feature;

import java.util.concurrent.*;

public class FiveFuture {

private static final Ad DEFAULT_AD = new Ad("无网络时候的默认广告");

private static final ExecutorService exec = Executors.newFixedThreadPool(10);

static class Ad {

String name;

public Ad(String name) {

this.name = name;

}

@Override

public String toString() {

return "Ad{" +

"name='" + name + '\'' +

'}';

}

}

static class FetchAdTask implements Callable {

@Override

public Ad call() throws Exception {

try {

Thread.sleep(3000);

} catch (InterruptedException e) {

System.out.println("sleep期间被中断了");

return new Ad("被中断时候的默认广告");

}

return new Ad("旅游订票哪家强?找某程");

}

}

public void printAd() {

Future f = exec.submit(new FetchAdTask());

Ad ad;

try {

ad = f.get(2000, TimeUnit.MILLISECONDS);

} catch (InterruptedException e) {

ad = new Ad("被中断时候的默认广告");

} catch (ExecutionException e) {

ad = new Ad("异常时候的默认广告");

} catch (TimeoutException e) {

ad = new Ad("超时时候的默认广告");

System.out.println("超时,未获取到广告");

boolean cancel = f.cancel(true);

System.out.println("cancel的结果:" + cancel);

}

exec.shutdown();

System.out.println(ad);

}

public static void main(String[] args) {

FiveFuture timeout = new FiveFuture();

timeout.printAd();

}

}

运行结果:

Disconnected from the target VM, address: '127.0.0.1:55224', transport: 'socket'

超时,未获取到广告

sleep期间被中断了

cancel的结果:true

Ad{name='超时时候的默认广告'}

Process finished with exit code 0

说明:

cancel方法传入true,则运行的方法会抛出异常

6.calcel的说明

64d6cc0ce5042992248b270dd0fbbe2d.png

7.传入false的作用

如果任务没有开始,false传入,任务会被打上标记,然后任务不会被执行。

8.传入true还是false

true适用:

任务能够处理interrupt

false:

未能处理interrupt的任务

不清楚任务是否支持取消

五:FutureTask创建Future

1.结构

1c8fea6f7777e54dcb7d82fc43888e76.png

2.程序

package com.jun.juc.feature;

import java.util.concurrent.Callable;

import java.util.concurrent.ExecutionException;

import java.util.concurrent.ExecutorService;

import java.util.concurrent.Executors;

import java.util.concurrent.FutureTask;

/**

* 描述: 演示FutureTask的用法

*/

public class FutureTaskDemo {

public static void main(String[] args) {

Task task = new Task();

FutureTask integerFutureTask = new FutureTask<>(task);

// new Thread(integerFutureTask).start();

ExecutorService service = Executors.newCachedThreadPool();

service.submit(integerFutureTask);

try {

System.out.println("task运行结果:"+integerFutureTask.get());

} catch (InterruptedException e) {

e.printStackTrace();

} catch (ExecutionException e) {

e.printStackTrace();

}

}

}

class Task implements Callable {

@Override

public Integer call() throws Exception {

System.out.println("子线程正在计算");

Thread.sleep(3000);

int sum = 0;

for (int i = 0; i < 100; i++) {

sum += i;

}

return sum;

}

}

效果:

Connected to the target VM, address: '127.0.0.1:55709', transport: 'socket'

子线程正在计算

task运行结果:4950

Disconnected from the target VM, address: '127.0.0.1:55709', transport: 'socket'

Process finished with exit code 1

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值