1️⃣ Создание пула потоков
Для начала нужно создать экземпляр
ExecutorService, который будет представлять ваш пул потоков. В этом примере мы создадим фиксированный пул из 5 потоков:ExecutorService executor = Executors.newFixedThreadPool(5);
2️⃣ Отправка задач для выполнения
После создания пула, вы можете отправлять ему задачи с помощью метода
submit(). В качестве примера, давайте создадим несколько задач, которые будут выполняться параллельно:for (int i = 0; i < 10; i++) {
final int taskId = i;
executor.submit(() -> {
System.out.println("Задача " + taskId + " выполняется в: " + Thread.currentThread().getName());
// Имитация длительной задачи
try {
Thread.sleep(1000); // Задержка на 1 секунду
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
System.out.println("Задача " + taskId + " завершена в: " + Thread.currentThread().getName());
});
}3️⃣ Завершение работы пула
После того как все задачи были отправлены, важно завершить работу пула, чтобы освободить ресурсы:
executor.shutdown(); // Ждем завершения всех задач
В этом примере создается пул из 5 потоков, и на него отправляется 10 задач. Поскольку пул состоит из 5 потоков, одновременно будут выполняться не более 5 задач. Остальные задачи будут ожидать своей очереди. Это демонстрирует, как Thread Pool управляет ресурсами и оптимизирует обработку задач.
При использовании Thread Pool вы можете быть уверены, что ваше приложение будет работать более эффективно, избегая затрат на создание новых потоков и управляя нагрузкой на систему.
#java #FixedThreadPool
Please open Telegram to view this post
VIEW IN TELEGRAM
👍7❤1
public class Quest {
public static void main(String[] args) {
System.out.print(op1() + op2() * op3());
}
private static int op1() {
System.out.print(1);
return 1;
}
private static int op2() {
System.out.print(2);
return 2;
}
private static int op3() {
System.out.print(3);
return 3;
}
}#java #quest
👍3👎2❤1
🤯15👍8🎉1
Reflection — это механизм в Java, который позволяет программам анализировать и манипулировать объектами во время выполнения. С помощью рефлексии вы можете:
✔️ Получать информацию о классах, методах и полях. Это позволяет динамически исследовать структуры данных вашего приложения.
✔️ Создавать экземпляры классов: Вы можете создавать объекты, не зная их тип на этапе компиляции.
✔️ Вызывать методы динамически: Это дает возможность запускать методы объектов, основываясь на их именах, переданных в виде строк.
✔️ Изменять значения полей: Вы можете динамически изменять значения полей объектов, что может быть особенно полезно в контексте тестирования или сериализации.
Преимущества использования рефлексии:
✔️ Потенциал для создания более абстрактного кода: Вы можете реализовать паттерны проектирования, такие как Dependency Injection.
✔️ Упрощение работы с библиотеками и фреймворками: Многие популярные библиотеки, такие как Spring и Hibernate, активно используют рефлексию для создания и управления объектами.
В следующем посте мы рассмотрим конкретные примеры использования рефлексии на практике. Оставайтесь с нами! 🚀
#Java #Метапрограммирование #Reflection
Please open Telegram to view this post
VIEW IN TELEGRAM
👍8
Продолжаем тему метапрограммирования и поговорим о том, как реализовать паттерн проектирования Dependency Injection (DI) с использованием рефлексии. DI позволяет нам разделить зависимости и упростить управление ими, что делает код более чистым и тестируемым.
Пример: Простой контейнер для Dependency Injection
В этом примере мы создадим простой контейнер, который будет автоматически связывать зависимости на основе аннотаций. Для этого нам понадобятся:
1. Аннотация @Inject для пометки полей, которые мы хотим внедрить.
2. Контейнер для обработки аннотаций и создания объектов.
Шаг 1: Создаем аннотацию
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@Retention(RetentionPolicy.RUNTIME)
@interface Inject {}
Шаг 2: Создаем классы с зависимостями
class Service {
public void serve() {
System.out.println("Service is working!");
}
}
class Client {
@Inject
private Service service;
public void doSomething() {
service.serve();
}
}
Шаг 3: Реализуем контейнер для Dependency Injection
import java.lang.reflect.Field;
class DIContainer {
public static void inject(Object obj) {
Class<?> clazz = obj.getClass();
for (Field field : clazz.getDeclaredFields()) {
if (field.isAnnotationPresent(Inject.class)) {
try {
field.setAccessible(true); // Делаем поле доступным
Object dependency = field.getType().getDeclaredConstructor().newInstance(); // Создаем экземпляр зависимости
field.set(obj, dependency); // Внедряем зависимость
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
}
Шаг 4: Используем наш контейнер
public class Main {
public static void main(String[] args) {
Client client = new Client();
DIContainer.inject(client); // Внедряем зависимости
client.doSomething(); // Вывод: Service is working!
}
}
Как это работает?
1️⃣ Мы создаем аннотацию
@Inject, чтобы пометить поля, которые должны быть внедрены.2️⃣ В классе
Client поле service помечено этой аннотацией.3️⃣ Контейнер
DIContainer проходит по полям класса, ищет аннотацию @Inject, и, если находит, создает объект зависимости и устанавливает его в поле.4️⃣ Когда мы вызываем метод
doSomething, объект Service успешно внедрен, и мы можем использовать его методы.#Java #Метапрограммирование #DependencyInjection
Please open Telegram to view this post
VIEW IN TELEGRAM
👍10🔥3❤1
public class Quest {
public static void main(String[] args) {
System.out.println(4_32l + 4_32l);
}
}👍4👎2
❤3🎉1
🚀 Усовершенствования в области параллелизма:
Project Loom — это инициатива в Java, которая вводит легковесные потоки (или корутины), делая асинхронное программирование более простым и понятным. Он позволяет разработчикам создавать и управлять огромным количеством потоков с минимальными затратами на ресурсы.
Почему это важно?
С использованием Project Loom вы сможете писать асинхронный код в синхронном стиле, что улучшает читаемость и упрощает отладку. Это значит меньше вложенных колбеков и легче управляемый код.
Как это работает?
Потоки в Project Loom называются "виртуальными", и вы можете создавать их так же просто, как обычные:
В этом примере мы создаем виртуальный поток, который выводит сообщение в консоль. Основной поток продолжает выполнять свою работу параллельно, что показывает, как просто можно организовать параллелизм без сложных конструкций.
Project Loom облегчает жизнь разработчикам, позволяя создавать многопоточные приложения проще и удобнее.
Project LoomProject Loom — это инициатива в Java, которая вводит легковесные потоки (или корутины), делая асинхронное программирование более простым и понятным. Он позволяет разработчикам создавать и управлять огромным количеством потоков с минимальными затратами на ресурсы.
Почему это важно?
С использованием Project Loom вы сможете писать асинхронный код в синхронном стиле, что улучшает читаемость и упрощает отладку. Это значит меньше вложенных колбеков и легче управляемый код.
Как это работает?
Потоки в Project Loom называются "виртуальными", и вы можете создавать их так же просто, как обычные:
public class LoomExample {
public static void main(String[] args) {
// Создаем виртуальный поток
Thread.startVirtualThread(() -> {
System.out.println("Hello from a virtual thread!");
});
// Основной поток продолжает работу
System.out.println("Hello from the main thread!");
}
}
В этом примере мы создаем виртуальный поток, который выводит сообщение в консоль. Основной поток продолжает выполнять свою работу параллельно, что показывает, как просто можно организовать параллелизм без сложных конструкций.
Project Loom облегчает жизнь разработчикам, позволяя создавать многопоточные приложения проще и удобнее.
👍12❤1
Если у вас есть поток, который может содержать повторяющиеся элементы, используйте операцию
distinct(), чтобы удалить их.
var list = Arrays.asList(1, 2, 3, 3, 4, 5, 5);
var distinctList = list.stream()
.distinct()
.collect(Collectors.toList());
// distinctList: [1, 2, 3, 4, 5]
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4
🚀 Реактивное программирование с помощью Project Reactor
Реактивное программирование — это новый подход к созданию асинхронных и масштабируемых приложений. Project Reactor — библиотека для Java, которая делает этот процесс простым и эффективным.
🔍 Что такое Project Reactor?
Project Reactor предоставляет инструменты для работы с потоками данных, основанные на спецификации Reactive Streams. Это дает возможность обрабатывать асинхронные события, используя:
1. Mono: асинхронный поток, который возвращает 0 или 1 элемент. Идеален для единичных значений.
2. Flux: поток, который может вернуть 0, 1 или много элементов. Отлично подходит для работы с коллекциями данных.
⚡ Преимущества Project Reactor:
🏎️ Высокая производительность: Неблокирующая модель усиливает эффективность использования ресурсов.
🛠️ Простой в обработке ошибок: Реактивные методы делают управление ошибками интуитивным.
📜 Читабельный код: Операторы позволяют писать более чистый и понятный код.
Реактивное программирование — это новый подход к созданию асинхронных и масштабируемых приложений. Project Reactor — библиотека для Java, которая делает этот процесс простым и эффективным.
🔍 Что такое Project Reactor?
Project Reactor предоставляет инструменты для работы с потоками данных, основанные на спецификации Reactive Streams. Это дает возможность обрабатывать асинхронные события, используя:
1. Mono: асинхронный поток, который возвращает 0 или 1 элемент. Идеален для единичных значений.
2. Flux: поток, который может вернуть 0, 1 или много элементов. Отлично подходит для работы с коллекциями данных.
⚡ Преимущества Project Reactor:
🏎️ Высокая производительность: Неблокирующая модель усиливает эффективность использования ресурсов.
🛠️ Простой в обработке ошибок: Реактивные методы делают управление ошибками интуитивным.
📜 Читабельный код: Операторы позволяют писать более чистый и понятный код.
❤5
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
public class ProjectReactorExample {
public static void main(String[] args) {
// Пример с Mono
Mono<String> monoExample = Mono.just("Hello, Reactor!");
monoExample
.map(String::toUpperCase) // Преобразуем строку в верхний регистр
.subscribe(System.out::println); // Подписываемся и выводим результат
// Пример с Flux
Flux<Integer> fluxExample = Flux.just(1, 2, 3, 4, 5);
fluxExample
.filter(num -> num % 2 == 0) // Фильтруем четные числа
.map(num -> num * num) // Возводим в квадрат
.subscribe(System.out::println); // Подписываемся и выводим результат
}
}
🔍 Что происходит в коде?
1. Mono:
- Создаем экземпляр
Mono с помощью Mono.just(), передавая строку.- Используем метод
map(), чтобы преобразовать строку в верхний регистр.- Подписываемся на
Mono с помощью subscribe, который выводит результат.2. Flux:
- Создаем экземпляр
Flux с числовыми значениями от 1 до 5.- Фильтруем четные числа с помощью
filter().- Применяем
map(), чтобы возвести каждое четное число в квадрат.- Подписываемся на
Flux и выводим результат.Please open Telegram to view this post
VIEW IN TELEGRAM
2👍4❤1
public class Quest {
public static final Quest INSTANCE = new Quest();
private final int yearsAgo;
private static final int CURRENT_YEAR = Calendar.getInstance().get(Calendar.YEAR);
private Quest() {
yearsAgo = CURRENT_YEAR - 2000;
}
public int yearsAgo() {
return yearsAgo;
}
public static void main(String[] args) {
System.out.println(INSTANCE.yearsAgo());
}
}👍1
🎉3👍1
Основные возможности SpEL:
✔️ Обращение к свойствам:
person.name✔️Вызов методов:
person.getName()✔️ Работа с коллекциями: фильтрация и проекция (
list.?[property > 10]).✔️ Логические и арифметические операции:
age > 18 && hasLicense✔️ Доступ к бинам Spring:
@beanName.method()Простой пример:
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
public class SpELExample {
public static void main(String[] args) {
ExpressionParser parser = new SpelExpressionParser();
// Пример вычисления простого выражения
String expression = "'Hello, Spring SpEL!'.toUpperCase()";
String result = parser.parseExpression(expression).getValue(String.class);
System.out.println(result); // Вывод: HELLO, SPRING SPEL!
}
}
Использование в аннотациях:
@Component
public class MyBean {
@Value("#{T(java.lang.Math).random() * 100}")
private double randomValue;
@Value("#{systemProperties['user.name']}")
private String userName;
public void printValues() {
System.out.println("Random Value: " + randomValue);
System.out.println("User Name: " + userName);
}
}
✔️
T(java.lang.Math).random() — вызов статического метода Math.random().✔️
systemProperties['user.name'] — доступ к системным свойствам.Использование с коллекциями:
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import java.util.Arrays;
import java.util.List;
public class CollectionExample {
public static void main(String[] args) {
ExpressionParser parser = new SpelExpressionParser();
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
// Фильтрация списка
List<Integer> filteredNumbers = (List<Integer>) parser.parseExpression(
"#numbers.?[#this > 2]").getValue(new StandardEvaluationContext(), numbers);
System.out.println(filteredNumbers); // Вывод: [3, 4, 5]
}
}
SpEL является удобным инструментом для внедрения динамического поведения и вычислений в приложениях Spring.
Please open Telegram to view this post
VIEW IN TELEGRAM
1👍9❤3
public class Quest {
public static void main(String[] args) {
String s = null;
System.out.println(s instanceof String);
}
}👍2
Что выведет код?
Anonymous Quiz
39%
true
26%
false
29%
<NullPointerException>
6%
<Ошибка компиляции>
👍4🎉1
public class Quest {
public static void greet() {
System.out.println("Hello world!");
}
public static void main(String[] args) {
Quest q = null;
q.greet();
}
}👍3
👍3🎉3😁2❤1
Enum.Внутренне
EnumMap использует массив для хранения значений, где индекс массива соответствует порядковому номеру (ordinal()) элемента перечисления. Это делает его быстрее, чем хэш-таблицы (HashMap) и более экономным по памяти.EnumMap хранит ключи в порядке их объявления в перечислении, что отличает его от большинства других Map (кроме LinkedHashMap).Так как ключи строго ограничены перечислением, это снижает вероятность ошибок при разработке.
🔍 Пример:
import java.util.EnumMap;
enum Action {
START, STOP, PAUSE
}
public class EnumMapExample {
public static void main(String[] args) {
EnumMap<Action, Runnable> actionMap = new EnumMap<>(Action.class);
// Определяем поведение для каждого значения Enum
actionMap.put(Action.START, () -> System.out.println("Starting the process..."));
actionMap.put(Action.STOP, () -> System.out.println("Stopping the process..."));
actionMap.put(Action.PAUSE, () -> System.out.println("Pausing the process..."));
// Пример вызова
Action currentAction = Action.START;
actionMap.get(currentAction).run();
}
}
#Java #EnumMap
Please open Telegram to view this post
VIEW IN TELEGRAM
👍19❤5