最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java 異步實(shí)現(xiàn)的幾種方式小結(jié)

 更新時(shí)間:2021年08月16日 10:09:12   作者:Amber揣手手  
這篇文章主要介紹了Java 異步實(shí)現(xiàn)的幾種方式小結(jié),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

Java 異步實(shí)現(xiàn)的幾種方式

1. jdk1.8之前的Future

jdk并發(fā)包里的Future代表了未來的某個(gè)結(jié)果,當(dāng)我們向線程池中提交任務(wù)的時(shí)候會(huì)返回該對(duì)象,可以通過future獲得執(zhí)行的結(jié)果,但是jdk1.8之前的Future有點(diǎn)雞肋,并不能實(shí)現(xiàn)真正的異步,需要阻塞的獲取結(jié)果,或者不斷的輪詢。

通常我們希望當(dāng)線程執(zhí)行完一些耗時(shí)的任務(wù)后,能夠自動(dòng)的通知我們結(jié)果,很遺憾這在原生jdk1.8之前是不支持的,但是我們可以通過第三方的庫實(shí)現(xiàn)真正的異步回調(diào)。

/**
 * jdk1.8之前的Future
 * @author Administrator
 */
public class JavaFuture {
	public static void main(String[] args) throws Throwable, ExecutionException {
		ExecutorService executor = Executors.newFixedThreadPool(1);
		Future<String> f = executor.submit(new Callable<String>() {
 
			@Override
			public String call() throws Exception {
				System.out.println("task started!");
				longTimeMethod();
				System.out.println("task finished!");
				return "hello";
			}
		});
 
		//此處get()方法阻塞main線程
		System.out.println(f.get());
		System.out.println("main thread is blocked");
	}
}

如果想獲得耗時(shí)操作的結(jié)果,可以通過get()方法獲取,但是該方法會(huì)阻塞當(dāng)前線程,我們可以在做完剩下的某些工作的時(shí)候調(diào)用get()方法試圖去獲取結(jié)果。

也可以調(diào)用非阻塞的方法isDone來確定操作是否完成,isDone這種方式有點(diǎn)兒類似下面的過程:

在這里插入圖片描述

2. jdk1.8開始的Future

直到j(luò)dk1.8才算真正支持了異步操作,jdk1.8中提供了lambda表達(dá)式,使得java向函數(shù)式語言又靠近了一步。借助jdk原生的CompletableFuture可以實(shí)現(xiàn)異步的操作,同時(shí)結(jié)合lambada表達(dá)式大大簡(jiǎn)化了代碼量。代碼例子如下:

package netty_promise; 
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.function.Supplier;
 
/**
 * 基于jdk1.8實(shí)現(xiàn)任務(wù)異步處理
 * @author Administrator
 */
public class JavaPromise {
	public static void main(String[] args) throws Throwable, ExecutionException {
		// 兩個(gè)線程的線程池
		ExecutorService executor = Executors.newFixedThreadPool(2);
		//jdk1.8之前的實(shí)現(xiàn)方式
		CompletableFuture<String> future = CompletableFuture.supplyAsync(new Supplier<String>() {
			@Override
			public String get() {
				System.out.println("task started!");
				try {
					//模擬耗時(shí)操作
					longTimeMethod();
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				return "task finished!";
			}
		}, executor);
 
		//采用lambada的實(shí)現(xiàn)方式
		future.thenAccept(e -> System.out.println(e + " ok"));
		
		System.out.println("main thread is running");
	}
}

實(shí)現(xiàn)方式類似下圖:

在這里插入圖片描述

3. Spring的異步方法

先把longTimeMethod 封裝到Spring的異步方法中,這個(gè)異步方法的返回值是Future的實(shí)例。這個(gè)方法一定要寫在Spring管理的類中,注意注解@Async。

@Service
public class AsynchronousService{
  @Async
  public Future springAsynchronousMethod(){
    Integer result = longTimeMethod();
    return new AsyncResult(result);
  }
}

其他類調(diào)用這個(gè)方法。這里注意,一定要其他的類,如果在同類中調(diào)用,是不生效的。

@Autowired
private AsynchronousService asynchronousService;
public void useAsynchronousMethod(){
    Future future = asynchronousService.springAsynchronousMethod();
    future.get(1000, TimeUnit.MILLISECONDS);
}

其實(shí)Spring只不過在原生的Future中進(jìn)行了一次封裝,我們最終獲得的還是Future實(shí)例。

4. Java如何將異步調(diào)用轉(zhuǎn)為同步

換句話說,就是需要在異步調(diào)用過程中,持續(xù)阻塞至獲得調(diào)用結(jié)果。

  • 使用wait和notify方法
  • 使用條件鎖
  • Future
  • 使用CountDownLatch
  • 使用CyclicBarrier

五種方法,具體舉例說明這篇文章

java異步任務(wù)處理

1、場(chǎng)景

最近做項(xiàng)目的時(shí)候遇到了一個(gè)小問題:從前臺(tái)提交到服務(wù)端A,A調(diào)用服務(wù)端B處理超時(shí),原因是前端一次請(qǐng)求往db插1萬數(shù)據(jù),插完之后會(huì)去清理緩存、發(fā)送消息。

服務(wù)端的有三個(gè)操作 a、插DB b、清理cache c、發(fā)送消息。1萬條數(shù)據(jù),說多不多,說少不少.況且不是單單insert。出現(xiàn)超時(shí)現(xiàn)象,不足為奇了吧~~

2、分析

如何避免超時(shí)呢?一次請(qǐng)求處理辣么多數(shù)據(jù),可分多次請(qǐng)求處理,每次請(qǐng)求處理100條數(shù)據(jù),可以有效解決超時(shí)問題. 為了不影響用戶的體驗(yàn),請(qǐng)求改為ajax 異步請(qǐng)求。

除此之外,仔細(xì)分析下場(chǎng)景. a 操作是本次處理的核心. 而b、c操作可以異步處理。換句話說,a操作處理完可以馬上返回給結(jié)果, 不必等b、c處理完再返回。b、c操作可以放在一個(gè)異步任務(wù)去處理。

3、實(shí)戰(zhàn)

(1)、ExecutorService : 任務(wù)提交

(2)、demo

異步任務(wù)類

public class ExecutorDemo {
    private ExecutorService executor = Executors.newFixedThreadPool(1);    
    public void asynTask() throws InterruptedException {    
        executor.submit(new Runnable() {            
            @Override
            public void run() {
                
                try {
                    Thread.sleep(10000);//方便觀察結(jié)果
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }                
                
                int sum = 0;
                for(int i = 0; i < 1000; i++) {                    
                    sum += i;
		    }                
                System.out.println(sum);
            }
        });        
    }
}

客戶端模擬

public class Client {
    public static void main(String[] args) throws InterruptedException {        
        boolean r = task2();        
        if(r) {
            task3();
        }        
        System.out.println("------------main end-----------");
    }
    
    static boolean task2() throws InterruptedException {        
        ExecutorDemo e = new ExecutorDemo();        
        e.asynTask();        
        System.out.println("------------task2 end-----------");        
        return true;
    }    
    
    static void task3() throws InterruptedException {
        int j = 0;
        while(true) {
            if(j++ > 10000) {
                break;
            }
        }
        
        System.out.println("------------task3 end-----------");
    }
} 

結(jié)果是醬紫的

------------task2 end-----------

------------task3 end-----------

------------main end-----------

499500

我們來分析下結(jié)果, task2是個(gè)異步任務(wù),執(zhí)行到task2,主線程不會(huì)在task2 阻塞,不用等待task2 處理完,可以往下執(zhí)行task3.

相關(guān)文章

  • Spring MVC請(qǐng)求參數(shù)接收的全面總結(jié)教程

    Spring MVC請(qǐng)求參數(shù)接收的全面總結(jié)教程

    這篇文章主要給大家總結(jié)介紹了關(guān)于Spring MVC請(qǐng)求參數(shù)接收的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2018-08-08
  • Java?MyBatis是如何執(zhí)行一條SQL語句的

    Java?MyBatis是如何執(zhí)行一條SQL語句的

    這篇文章主要介紹了Java?MyBatis是如何執(zhí)行一條SQL語句的,文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的小伙伴可以參考一下
    2022-07-07
  • Java中的functor實(shí)現(xiàn)

    Java中的functor實(shí)現(xiàn)

    Java中的functor實(shí)現(xiàn)...
    2006-12-12
  • 東方通TongWeb結(jié)合Spring-Boot使用的實(shí)現(xiàn)

    東方通TongWeb結(jié)合Spring-Boot使用的實(shí)現(xiàn)

    本文主要介紹了東方通TongWeb結(jié)合Spring-Boot使用的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2024-07-07
  • BaseDao封裝JavaWeb的增刪改查的實(shí)現(xiàn)代碼

    BaseDao封裝JavaWeb的增刪改查的實(shí)現(xiàn)代碼

    Basedao 是一種基于數(shù)據(jù)訪問對(duì)象(Data Access Object)模式的設(shè)計(jì)方法,它是一個(gè)用于處理數(shù)據(jù)庫操作的基礎(chǔ)類,負(fù)責(zé)封裝數(shù)據(jù)庫訪問的底層操作,提供通用的數(shù)據(jù)庫訪問方法,本文給大家介紹了BaseDao封裝JavaWeb的增刪改查的實(shí)現(xiàn)代碼,需要的朋友可以參考下
    2024-03-03
  • SpringBoot和前端聯(lián)動(dòng)實(shí)現(xiàn)存儲(chǔ)瀏覽記錄功能

    SpringBoot和前端聯(lián)動(dòng)實(shí)現(xiàn)存儲(chǔ)瀏覽記錄功能

    這篇文章主要介紹了SpringBoot和前端聯(lián)動(dòng)實(shí)現(xiàn)存儲(chǔ)瀏覽記錄功能,本文通過示例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧
    2024-01-01
  • MyBatis在DAO層定義接口返回類型泛型無效的解決

    MyBatis在DAO層定義接口返回類型泛型無效的解決

    這篇文章主要介紹了MyBatis在DAO層定義接口返回類型泛型無效的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-07-07
  • SpringMVC圖片文件跨服務(wù)器上傳

    SpringMVC圖片文件跨服務(wù)器上傳

    這篇文章主要為大家詳細(xì)介紹了SpringMVC圖片文件跨服務(wù)器上傳,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-08-08
  • Java如何使用正則表達(dá)式從字符串中提取數(shù)字

    Java如何使用正則表達(dá)式從字符串中提取數(shù)字

    這篇文章主要介紹了Java如何使用正則表達(dá)式從字符串中提取數(shù)字問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-12-12
  • 解決cmd執(zhí)行javac報(bào)錯(cuò):不是內(nèi)部或外部命令,也不是可運(yùn)行的程序

    解決cmd執(zhí)行javac報(bào)錯(cuò):不是內(nèi)部或外部命令,也不是可運(yùn)行的程序

    剛接觸JAVA的新手可能就不知道怎么解決'JAVAC'不是內(nèi)部命令或外部命令,這篇文章主要給大家介紹了關(guān)于解決cmd執(zhí)行javac報(bào)錯(cuò):不是內(nèi)部或外部命令,也不是可運(yùn)行的程序的相關(guān)資料,需要的朋友可以參考下
    2023-11-11

最新評(píng)論

大名县| 苏尼特左旗| 潞城市| 扬中市| 民权县| 慈溪市| 淄博市| 葫芦岛市| 大庆市| 金山区| 那曲县| 石柱| 宽城| 兴义市| 滦南县| 汕尾市| 乐山市| 和静县| 察雅县| 遵化市| 铜山县| 芜湖市| 崇义县| 北流市| 鄂托克旗| 浦江县| 潜江市| 柘荣县| 丘北县| 东丽区| 怀来县| 正定县| 卓资县| 宣武区| 漠河县| 九龙城区| 巨鹿县| 志丹县| 泰和县| 城固县| 仪征市|