600字范文,内容丰富有趣,生活中的好帮手!
600字范文 > java判断线程阻塞_JDK.Future.get() :多线程里获取线程执行结果 异步阻塞问题

java判断线程阻塞_JDK.Future.get() :多线程里获取线程执行结果 异步阻塞问题

时间:2021-09-03 19:52:53

相关推荐

java判断线程阻塞_JDK.Future.get() :多线程里获取线程执行结果 异步阻塞问题

为了保证系统响应迅速,需要寻找一种方法能够使调取接口能够异步执行,而Java正好提供了类似的方法,在java.util.concurrent中包含了Future相关的类,运用其中的一些类可以进行异步计算,以减少主线程的等待时间。比如启动一个main方法,main中又包含了若干个其它任务,在不使用Java future的情况下,main方法中的任务会同步阻塞执行,一个执行完成后,才能去执行另一个;如果使用java future,则main方法中的任务会异步执行,main方法不用等待一个任务的执行完成,只需往下执行就行。一个任务的执行结果又该怎么获取呢?这里就需要用到Future接口中的isDone()方法来判断任务是否执行完,如果执行完成则可获取结果,如果没有完成则需要等待。**可见虽然主线程中的多个任务是异步执行,但是无法确定任务什么时候执行完成,只能通过不断去监听以获取结果,所以这里是阻塞的。这样,可能某一个任务执行时间很长会拖累整个主任务的执行。**

还是那句话,废话不多说,直接上代码:

package com.aplus.controller;

import lombok.extern.slf4j.Slf4j;

import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.RestController;

import java.util.Random;

import java.util.concurrent.Callable;

import java.util.concurrent.ExecutorService;

import java.util.concurrent.Executors;

import java.util.concurrent.Future;

/**

* @author whb

*/

@Slf4j

@RestController

@RequestMapping(value = "/api/guava")

public class GuavaController {

public static final ExecutorService service = Executors.newCachedThreadPool();

public static void main(String[] args) throws Exception {

long start = System.currentTimeMillis();

// 任务1

Future booleanTask = service.submit(new Callable() {

@Override

public Boolean call() throws Exception {

Thread.sleep(10000);

return true;

}

});

// 任务2

Future stringTask = service.submit(new Callable() {

@Override

public String call() throws Exception {

Thread.sleep(3000);

return "Hello World";

}

});

// 任务3

Future integerTask = service.submit(new Callable() {

@Override

public Integer call() throws Exception {

Thread.sleep(2000);

return new Random().nextInt(100);

}

});

while (true) {

if (booleanTask.isDone() && !booleanTask.isCancelled()) {

Boolean result = booleanTask.get();

System.err.println("任务1-10s: " + result);

break;

}

}

while (true) {

if (stringTask.isDone() && !stringTask.isCancelled()) {

String result = stringTask.get();

System.err.println("任务2-3s: " + result);

break;

}

}

while (true) {

if (integerTask.isDone() && !integerTask.isCancelled()) {

Integer result = integerTask.get();

System.err.println("任务3-2s:" + result);

break;

}

}

// 执行时间

System.err.println("time: " + (System.currentTimeMillis() - start));

}

}

解释一波:

启动一个线程池,有三个线程和三个任务,分别是线程1,线程2,线程3;线程1执行任务1(耗时10s),线程2执行任务2(耗时3s),线程3执行任务3(耗时2s);

Thread1 ——> Task1 10s

Thread2 ——> Task2 2s

Thread3 ——> Task3 3s

我们运行程序看效果:

![watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzMzMTAxNjc1_size_16_color_FFFFFF_t_70][]

因为我们一开始用 Thread1.get() 获取第一个线程的结果时,是阻塞的,而且我们假定任务1执行了10s钟,导致了线程2(3s就执行完任务)和线程3(2s就执行完任务)都执行完了任务,也不打印出来。那在实际业务中,这种方法肯定是不可取的。

所以接下来我们引入 [Guava Future](/article/details/1011093225221856)

[watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzMzMTAxNjc1_size_16_color_FFFFFF_t_70]: /images/1602422945647.png

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。