欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java處理多API請(qǐng)求的方法詳解

 更新時(shí)間:2023年10月13日 15:39:38   作者:Mey  
Java?中的并發(fā)是指語(yǔ)言并行運(yùn)行多個(gè)線(xiàn)程的能力,允許同時(shí)執(zhí)行多個(gè)任務(wù),

Java 中的并發(fā)是指語(yǔ)言并行運(yùn)行多個(gè)線(xiàn)程的能力,允許同時(shí)執(zhí)行多個(gè)任務(wù)。

線(xiàn)程池和Executor框架

一種方法是使用線(xiàn)程池來(lái)管理固定數(shù)量的線(xiàn)程,這些線(xiàn)程可以處理傳入的請(qǐng)求。Java Executor 框架提供了一種方便的方法來(lái)實(shí)現(xiàn)這種方法,換句話(huà)說(shuō),使用線(xiàn)程池和 Executor 框架是在 Java 中實(shí)現(xiàn)并發(fā)和處理多個(gè) API 請(qǐng)求的一種方法。

線(xiàn)程池管理固定數(shù)量的線(xiàn)程,可以有效利用系統(tǒng)資源,防止線(xiàn)程饑餓。

什么是執(zhí)行器框架?

Executor 框架是一個(gè)內(nèi)置的 Java 框架,它提供了一種管理和執(zhí)行線(xiàn)程的方法。它是 java.util.concurrent 包的一部分,在 Java 5 中引入。

Executor 框架在低級(jí) Thread 類(lèi)上提供了更高級(jí)別的抽象,從而更容易并發(fā)執(zhí)行任務(wù),而無(wú)需直接管理線(xiàn)程。它還提供了一種方法來(lái)管理線(xiàn)程池并重用它們來(lái)執(zhí)行多個(gè)任務(wù),從而減少創(chuàng)建和銷(xiāo)毀線(xiàn)程的開(kāi)銷(xiāo)。

Executor框架的核心接口是Executor接口,它定義了一個(gè)單一的方法execute(Runnable)。Executor 接口提供了一種提交 Runnable 任務(wù)以供執(zhí)行的方法。該框架還提供了一些子接口和類(lèi),可以用來(lái)實(shí)現(xiàn)不同類(lèi)型的Executor,例如:

  • ExecutorService:一個(gè) Executor,它提供管理終止的方法和可以生成用于跟蹤一個(gè)或多個(gè)異步任務(wù)進(jìn)度的 Future 的方法。
  • ScheduledExecutorService:一個(gè) ExecutorService,它可以安排命令在給定延遲后運(yùn)行,或定期執(zhí)行。
  • ThreadPoolExecutor:一個(gè) ExecutorService,它使用可能的多個(gè)池線(xiàn)程之一執(zhí)行每個(gè)提交的任務(wù),通常使用 Executors 工廠方法配置。

使用 Executor 框架可以幫助您以高效的方式處理多個(gè) API 請(qǐng)求,方法是管理線(xiàn)程并提供一種將它們重用于多個(gè)任務(wù)的方法,從而減少創(chuàng)建和銷(xiāo)毀線(xiàn)程的開(kāi)銷(xiāo)。

下面是一個(gè)如何使用 Executor 框架高效處理多個(gè) API 請(qǐng)求的示例:

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class ExecutorExample {
    public static void main(String[] args) {
        // Create a fixed thread pool with 5 threads
        ExecutorService executor = Executors.newFixedThreadPool(5);
        // Submit 10 tasks for execution
        for (int i = 0; i < 10; i++) {
            final int taskId = i;
            executor.submit(new Runnable() {
                @Override
                public void run() {
                    // Perform an API request here
                    // For example, using the OkHttp library:
                    // OkHttpClient client = new OkHttpClient();
                    // Request request = new Request.Builder()
                    //          .url("https://example.com/api/task" + taskId)
                    //          .build();
                    // Response response = client.newCall(request).execute();
                    // Do something with the response
                    System.out.println("Task " + taskId + " completed");
                }
            });
        }
        // Shut down the executor
        executor.shutdown();
    }
}

在本例中,我們使用Executors.newFixedThreadPool方法創(chuàng)建一個(gè)具有 5 個(gè)線(xiàn)程的固定線(xiàn)程池。然后,我們使用該executor.submit方法提交 10 個(gè)要執(zhí)行的任務(wù)。每個(gè)任務(wù)代表一個(gè) API 請(qǐng)求,該請(qǐng)求將由線(xiàn)程池中的線(xiàn)程之一執(zhí)行。

提交所有任務(wù)后,shutdown()調(diào)用執(zhí)行器的方法,啟動(dòng)線(xiàn)程池的關(guān)閉。池中的線(xiàn)程將執(zhí)行完提交的任務(wù),然后終止。

請(qǐng)注意,在此示例中,我添加了一個(gè)用于發(fā)出 API 請(qǐng)求的虛擬代碼,它不起作用,您必須使用特定的庫(kù)(如 OkHttp 或 Retrofit)來(lái)進(jìn)行 API 調(diào)用。

您可以在這個(gè)示例中看到,通過(guò)重用固定數(shù)量的線(xiàn)程并通過(guò) Executor 框架管理任務(wù)的執(zhí)行,我們能夠并發(fā)且高效地處理多個(gè) API 請(qǐng)求。

異步 I/O 庫(kù)

在 Java 中實(shí)現(xiàn)并發(fā)的另一種方法是通過(guò)使用異步 I/O (AIO) 庫(kù),它允許非阻塞 I/O 操作,并且可以處理大量并發(fā)連接。

異步 I/O 庫(kù)是一個(gè)允許非阻塞 I/O 操作的庫(kù),這意味著程序可以在等待 I/O 操作完成的同時(shí)繼續(xù)執(zhí)行其他任務(wù)。這在處理大量并發(fā)連接時(shí)很有用,例如在構(gòu)建高性能服務(wù)器時(shí)。

Java 中異步 I/O 庫(kù)的一個(gè)例子是 Java NIO 包,自 Java 1.4 以來(lái)它是標(biāo)準(zhǔn) Java 庫(kù)的一部分。它提供了一組用于執(zhí)行非阻塞 I/O 操作的類(lèi)和接口。

下面是一個(gè)如何使用 Java NIO 包構(gòu)建可以同時(shí)處理多個(gè)客戶(hù)端的簡(jiǎn)單服務(wù)器的示例:

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Iterator;
public class NioServer {
    public static void main(String[] args) throws IOException {
        // Open a selector
        Selector selector = Selector.open();
        // Open a server socket channel
        ServerSocketChannel serverSocket = ServerSocketChannel.open();
        serverSocket.bind(new InetSocketAddress(8080));
        serverSocket.configureBlocking(false);
        // Register the server socket channel with the selector
        serverSocket.register(selector, SelectionKey.OP_ACCEPT);
        while (true) {
            // Wait for events
            selector.select();
            // Iterate over the events
            Iterator<SelectionKey> iterator = selector.selectedKeys().iterator();
            while (iterator.hasNext()) {
                SelectionKey key = iterator.next();
                // Handle a new connection
                if (key.isAcceptable()) {
                    ServerSocketChannel channel = (ServerSocketChannel) key.channel();
                    SocketChannel client = channel.accept();
                    client.configureBlocking(false);
                    client.register(selector, SelectionKey.OP_READ);
                }
                // Handle a read event
                if (key.isReadable()) {
                    SocketChannel client = (SocketChannel) key.channel();
                    ByteBuffer buffer = ByteBuffer.allocate(1024);
                    int read = client.read(buffer);
                    if (read > 0) {
                        buffer.flip();
                        String message = new String(buffer.array(), 0, read);
                        System.out.println("Received: " + message);
                    }
                }
                iterator.remove();
            }
        }
    }
}

在這個(gè)例子中,我們首先打開(kāi)一個(gè)Selector對(duì)象和一個(gè)ServerSocketChannel. 被ServerSocketChannel配置為非阻塞的并注冊(cè)到Selector. 然后我們進(jìn)入一個(gè)無(wú)限循環(huán),等待已注冊(cè)頻道上的事件。

當(dāng)接受新連接時(shí),我們SocketChannel為客戶(hù)端創(chuàng)建一個(gè)新連接并將其注冊(cè)到Selectorfor read 事件。當(dāng)檢測(cè)到讀取事件時(shí),我們將數(shù)據(jù)從客戶(hù)端讀取到緩沖區(qū)中并將其打印到控制臺(tái)。

可以看到,通過(guò)使用 Java NIO 包,我們可以同時(shí)處理多個(gè)客戶(hù)端,而不會(huì)阻塞程序的執(zhí)行。Selector以及ServerSocketChannel。

OkHttp 和 Retrofit

使用像 OkHttp 或 Retrofit 這樣的庫(kù)的概念也與并發(fā)密切相關(guān),因?yàn)樗橄罅说讓泳W(wǎng)絡(luò)和線(xiàn)程實(shí)現(xiàn),使開(kāi)發(fā)人員可以輕松高效地處理多個(gè)請(qǐng)求。

OkHttp

OkHttp 是一個(gè)流行的 Java 庫(kù),用于發(fā)出 HTTP 請(qǐng)求。它為執(zhí)行同步和異步請(qǐng)求提供了一個(gè)簡(jiǎn)單高效的 API。它還包括連接池、透明 GZIP 壓縮和響應(yīng)緩存等功能。

下面是如何使用 OkHttp 在多線(xiàn)程環(huán)境中發(fā)出異步 GET 請(qǐng)求的示例。

import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import java.io.IOException;
public class OkHttpAsyncExample {
    public static void main(String[] args) {
        OkHttpClient client = new OkHttpClient();
        Request request = new Request.Builder()
                .url("https://jsonplaceholder.typicode.com/todos/1")
                .build();
        client.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                e.printStackTrace();
            }
            @Override
            public void onResponse(Call call, Response response) throws IOException {
                if (!response.isSuccessful()) {
                    throw new IOException("Unexpected code " + response);
                }
                String responseBody = response.body().string();
                System.out.println(responseBody);
            }
        });
    }
}

在這個(gè)例子中,我們首先創(chuàng)建一個(gè)實(shí)例,OkHttpClient它是線(xiàn)程安全的,可以被多個(gè)請(qǐng)求共享。然后我們創(chuàng)建一個(gè)新Request對(duì)象,指定我們要調(diào)用的 URL。

然后我們使用該enqueue方法異步執(zhí)行請(qǐng)求。該enqueue方法采用一個(gè)Callback對(duì)象,在請(qǐng)求完成或失敗時(shí)調(diào)用該對(duì)象。在此示例中,我們?cè)诔晒r(shí)打印響應(yīng)主體,在失敗時(shí)打印異常堆棧跟蹤。

當(dāng)你有多個(gè)傳入的 API 請(qǐng)求時(shí),你可以對(duì)所有請(qǐng)求使用同一個(gè) OkHttpClient 實(shí)例,所有請(qǐng)求都將由 OkHttp 異步處理。該enqueue方法立即返回,允許您的應(yīng)用程序在后臺(tái)獲取響應(yīng)的同時(shí)繼續(xù)處理其他請(qǐng)求或任務(wù)。這有助于防止阻塞程序的執(zhí)行并確保在處理大量并發(fā)連接時(shí)具有良好的性能。

改裝

下面是如何使用 Retrofit 在多線(xiàn)程環(huán)境中發(fā)出異步 GET 請(qǐng)求的示例。

import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
public class RetrofitAsyncExample {
    public static void main(String[] args) {
        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl("https://jsonplaceholder.typicode.com/")
                .addConverterFactory(GsonConverterFactory.create())
                .build();
        JsonPlaceholderApi jsonPlaceholderApi = retrofit.create(JsonPlaceholderApi.class);
        Call<Todo> call = jsonPlaceholderApi.getTodo(1);
        call.enqueue(new Callback<Todo>() {
            @Override
            public void onResponse(Call<Todo> call, Response<Todo> response) {
                if (!response.isSuccessful()) {
                    System.out.println("Unexpected code " + response);
                    return;
                }
                Todo todo = response.body();
                System.out.println(todo);
            }
            @Override
            public void onFailure(Call<Todo> call, Throwable t) {
                t.printStackTrace();
            }
        });
    }
}
interface JsonPlaceholderApi {
    @GET("todos/{id}")
    Call<Todo> getTodo(@Path("id") int id);
}
class Todo {
    int userId;
    int id;
    String title;
    boolean completed;
    // getters and setters
}

在此示例中,我們首先Retrofit通過(guò)指定我們要調(diào)用的 API 的基本 URL 并添加一個(gè) GSON 轉(zhuǎn)換器工廠來(lái)創(chuàng)建一個(gè)實(shí)例。JsonPlaceholderApi然后我們使用 Retrofit 的方法創(chuàng)建一個(gè)接口create的實(shí)現(xiàn)來(lái)獲取服務(wù)的實(shí)現(xiàn)。

然后我們調(diào)用getTodo接口的方法,傳遞我們要檢索的待辦事項(xiàng)的 ID。這將返回一個(gè)Call對(duì)象,我們可以使用該對(duì)象通過(guò)調(diào)用異步執(zhí)行請(qǐng)求enqueue。

enqueue方法采用一個(gè)Callback對(duì)象,在請(qǐng)求完成或失敗時(shí)調(diào)用該對(duì)象。在此示例中,我們?cè)诔晒r(shí)打印響應(yīng)主體,在失敗時(shí)打印異常堆棧跟蹤。

當(dāng)你有多個(gè)傳入的 API 請(qǐng)求時(shí),你可以對(duì)所有請(qǐng)求使用相同的 Retrofit 實(shí)例,所有請(qǐng)求將由 Retrofit 異步處理。該enqueue方法立即返回,允許您的應(yīng)用程序在后臺(tái)獲取響應(yīng)的同時(shí)繼續(xù)處理其他請(qǐng)求或任務(wù)。這有助于防止阻塞程序的執(zhí)行并確保在處理大量并發(fā)連接時(shí)具有良好的性能。

總之,以高效方式處理多個(gè) API 請(qǐng)求的概念與 Java 中的并發(fā)性密切相關(guān),可以通過(guò)使用線(xiàn)程池、異步 I/O (AIO) 庫(kù)以及 OkHttp 或 Retrofit 等庫(kù)來(lái)實(shí)現(xiàn)。

以上就是Java處理多API請(qǐng)求的方法詳解的詳細(xì)內(nèi)容,更多關(guān)于Java處理多API請(qǐng)求的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Java如何導(dǎo)出zip壓縮文件

    Java如何導(dǎo)出zip壓縮文件

    這篇文章主要介紹了Java如何導(dǎo)出zip壓縮文件問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-07-07
  • springboot接收json數(shù)據(jù)時(shí),接收到空值問(wèn)題

    springboot接收json數(shù)據(jù)時(shí),接收到空值問(wèn)題

    這篇文章主要介紹了springboot接收json數(shù)據(jù)時(shí),接收到空值問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-05-05
  • Springboot+SpringSecurity實(shí)現(xiàn)圖片驗(yàn)證碼登錄的示例

    Springboot+SpringSecurity實(shí)現(xiàn)圖片驗(yàn)證碼登錄的示例

    本文主要介紹了Springboot+SpringSecurity實(shí)現(xiàn)圖片驗(yàn)證碼登錄的示例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2022-04-04
  • java 虛擬機(jī)深入了解

    java 虛擬機(jī)深入了解

    這篇文章主要介紹了java 虛擬機(jī)深入了解的相關(guān)資料,ava虛擬機(jī)有自己完善的硬體架構(gòu),如處理器、堆棧、寄存器等,還具有相應(yīng)的指令系統(tǒng),需要的朋友可以參考下
    2017-03-03
  • PowerJob分布式任務(wù)調(diào)度源碼流程解讀

    PowerJob分布式任務(wù)調(diào)度源碼流程解讀

    這篇文章主要為大家介紹了PowerJob分布式任務(wù)調(diào)度源碼流程解讀,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2024-02-02
  • struts2實(shí)現(xiàn)多文件上傳的示例代碼

    struts2實(shí)現(xiàn)多文件上傳的示例代碼

    本篇文章主要介紹了struts2實(shí)現(xiàn)多文件上傳的示例代碼,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-03-03
  • springboot2.0使用Hikari連接池的方法(替換druid)

    springboot2.0使用Hikari連接池的方法(替換druid)

    這篇文章主要介紹了springboot 2.0使用Hikari連接池的方法(替換druid),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-12-12
  • 解析spring-boot-starter-parent簡(jiǎn)介

    解析spring-boot-starter-parent簡(jiǎn)介

    本文通過(guò)代碼的形式給大家介紹了spring-boot-starter-parent的基礎(chǔ)知識(shí),需要的朋友可以參考下
    2018-09-09
  • 詳解spring cloud eureka注冊(cè)中心

    詳解spring cloud eureka注冊(cè)中心

    這篇文章主要介紹了詳解spring cloud eureka注冊(cè)中心,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-07-07
  • 淺談java的TCP和UDP編程(附實(shí)例講解)

    淺談java的TCP和UDP編程(附實(shí)例講解)

    下面小編就為大家?guī)?lái)一篇淺談java的TCP和UDP編程(附實(shí)例講解)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-05-05

最新評(píng)論