התכונה 'שרשורים וירטואליים', שהפכה לזמינה לכלל המשתמשים (GA) ב-JDK 21, מפשטת את הפיתוח של אפליקציות עם בו-זמניות (concurrency) גבוהה. בין היתרונות המרכזיים:
- תפוקה גבוהה יותר, במיוחד באפליקציות עם פעולות קלט/פלט חוסמות.
- אופטימיזציה של הזיכרון בגלל האופי הקליל שלהם.
- מודל פשוט של פעולות שמתבצעות בו-זמנית, שבו האפליקציות יכולות להיות מיוצגות בסגנון של שרשור לכל בקשה.
לפני שמחילים שרשורים וירטואליים על האפליקציה, כדאי לעיין בתיאור המפורט של היתרונות והמגבלות של התכונה הזו ב- JEP 444: Virtual Threads במסמכי התיעוד של Open JDK.
במדריך הזה מוסבר איך להגדיר את ספריות הלקוח של Cloud ל-Java במאגר googleapis/google-cloud-java לשימוש בשרשורים וירטואליים.
דרישות מוקדמות
כדי להשתמש בשרשורים וירטואליים עם ספריות הלקוח של Cloud ל-Java שבהן רוצים להשתמש באפליקציה, צריך לבצע את השלבים הבאים.
- אם עדיין לא עשיתם זאת, יוצרים Google Cloud פרויקט. איך יוצרים ומנהלים פרויקטים
- מתקינים את Google Cloud CLI, שמאפשר להריץ את הדוגמה עם פרטי הכניסה של הפרויקט.
מתחברים באמצעות Application Default Credentials באמצעות הפקודה הבאה. הוראות נוספות זמינות במאמר בנושא הגדרה של Application Default Credentials :
gcloud auth application-default loginכדי לוודא ש-Java Development Kit (JDK) 21 ואילך מותקן, מריצים את הפקודה
java -versionומוודאים שמוצג הפלט הבא. הוראות להתקנת JDK מופיעות במאמר הגדרת סביבת פיתוח בשפת Java.openjdk version "21.0.2" 2024-01-16 LTS OpenJDK Runtime Environment Temurin-21.0.2+13 (build 21.0.2+13-LTS) OpenJDK 64-Bit Server VM Temurin-21.0.2+13 (build 21.0.2+13-LTS, mixed mode, sharing)
ייבוא הספרייה לפרויקט
בדוגמה הזו נשתמש ב-google-cloud-translate. במאמר שימוש ב-Cloud Translation ל-Java מוסבר איך להשתמש בספרייה ב-Maven או ב-Gradle.
שימוש ב-virtual thread executor בספריות הלקוח
כשיוצרים מופע של מחלקה בספריית לקוח, אפשר לבחור את הטמעת התעבורה שלה (gRPC ו-REST).
העברה באמצעות REST
ספריות הלקוח שמטמיעות העברת REST משתמשות בקריאות חסימה של קלט/פלט ברשת, ונהנות משיפורי התפוקה שמתקבלים משימוש בשרשורים וירטואליים. בקטע הקוד הבא מוצג איך אפשר לנהל חסימה של תעבורת קלט/פלט ברשת בספריות הלקוח של Cloud ל-Java באמצעות שרשורים וירטואליים. אפשר להטמיע את זה באפליקציה שלכם על ידי החלפת ברירת המחדל של מנהל השרשורים במנהל שרשורים וירטואליים במופע TransportChannelProvider.
import com.google.cloud.translate.*;
import java.util.concurrent.Executors;
ExecutorService virtualThreadExecutor = Executors.newVirtualThreadPerTaskExecutor();
InstantiatingHttpJsonChannelProvider httpJsonChannelProvider =
TranslationServiceSettings.defaultHttpJsonTransportProviderBuilder()
// Use virtual threads for network I/O calls.
.setExecutor(virtualThreadExecutor)
.build();
try (TranslationServiceClient client =
TranslationServiceClient.create(
TranslationServiceSettings.newHttpJsonBuilder()
.setTransportChannelProvider(httpJsonChannelProvider)
.build())) {
// Make translate requests
}
העברה ב-gRPC
מכיוון ש-gRPC כבר משתמש בלוגיקה אסינכרונית לטיפול בבקשות, שיפורי התפוקה משרשורים וירטואליים עשויים להיות פחות בולטים. עם זאת, הן עדיין יכולות לספק יתרונות מסוימים של אופטימיזציה של הזיכרון בגלל האופי הקליל שלהן. בקטע הקוד הבא אפשר לראות איך אפשר לנהל פעולות העברה של gRPC באמצעות שרשורים וירטואליים. אפשר להטמיע את זה באפליקציה שלכם על ידי החלפת ברירת המחדל של מנהל השרשורים במנהל שרשורים וירטואליים במופע של TransportChannelProvider.
import com.google.cloud.translate.*;
import java.util.concurrent.Executors;
ExecutorService virtualThreadExecutor = Executors.newVirtualThreadPerTaskExecutor();
InstantiatingGrpcChannelProvider grpcChannelProvider =
TranslationServiceSettings.defaultGrpcTransportProviderBuilder()
// Use virtual threads for gRPC transport operations.
.setExecutor(virtualThreadExecutor)
.build();
try (TranslationServiceClient client =
TranslationServiceClient.create(
TranslationServiceSettings.newBuilder()
.setTransportChannelProvider(grpcChannelProvider)
.build())) {
// Make translate requests
}