Java for Beginner
672 subscribers
541 photos
155 videos
12 files
827 links
Канал от новичков для новичков!
Изучайте Java вместе с нами!
Здесь мы обмениваемся опытом и постоянно изучаем что-то новое!

Наш YouTube канал - https://www.youtube.com/@Java_Beginner-Dev

Наш канал на RUTube - https://rutube.ru/channel/37896292/
Download Telegram
Многопоточность в Java: Пул потоков

Пул потоков (Thread Pool) — это механизм управления коллекцией потоков, предназначенный для выполнения задач. Потоки в пуле повторно используются для выполнения нескольких задач, что позволяет сократить накладные расходы на создание и уничтожение потоков и повысить производительность многопоточных приложений.

Зачем нужен пул потоков?

Улучшение производительности: Создание нового потока — дорогостоящая операция. Пул потоков позволяет избежать этих накладных расходов, повторно используя уже существующие потоки.
Контроль над количеством потоков: Пул потоков позволяет ограничить максимальное количество одновременно работающих потоков, что предотвращает исчерпание ресурсов системы.
Упрощение управления задачами: Пул потоков предоставляет удобные методы для отправки задач на выполнение, что упрощает управление многопоточными задачами.


Создание пула потоков

В Java для работы с пулом потоков используется класс ExecutorService, который предоставляет методы для управления потоками и выполнения задач. Воспользоваться готовыми реализациями можно с помощью класса Executors.

Пример создания пула потоков с фиксированным числом потоков
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class FixedThreadPoolExample {

public static void main(String[] args) {
ExecutorService executorService = Executors.newFixedThreadPool(3);

for (int i = 0; i < 5; i++) {
int taskId = i;
executorService.submit(() -> {
System.out.println("Task " + taskId + " is running in thread " + Thread.currentThread().getName());
try {
Thread.sleep(2000); // Симуляция долгой задачи
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Task " + taskId + " completed");
});
}

executorService.shutdown();
}
}


В этом примере создается пул из трех потоков, и пять задач отправляются на выполнение. Задачи будут выполняться параллельно, но не более трех одновременно.



Виды пулов потоков

FixedThreadPool: Пул с фиксированным числом потоков. Новый поток не создается, если все потоки заняты, до тех пор, пока один из них не освободится.
ExecutorService fixedThreadPool = Executors.newFixedThreadPool(5);


CachedThreadPool: Пул, который создает потоки по мере необходимости, но переиспользует старые потоки, если они доступны. Подходит для выполнения большого количества коротких задач.
ExecutorService cachedThreadPool = Executors.newCachedThreadPool();


SingleThreadExecutor: Пул с единственным потоком, выполняющий задачи последовательно.
ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor();


ScheduledThreadPool: Пул, который позволяет выполнять задачи с задержкой или периодически.
ExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(3);


#Java #Training #Multithreading #Medium
Варианты ответа:
Anonymous Quiz
80%
3
0%
4
0%
5
20%
7
Что выведет код?

public class StringChallenge {
public static void main(String[] args) {
String str1 = "Java";
String str2 = new String("Java");
String str3 = "Ja" + "va";
String str4 = str2.intern();

boolean result1 = (str1 == str2);
boolean result2 = (str1 == str3);
boolean result3 = (str1 == str4);
boolean result4 = str1.equals(str2);

int sum = (result1 ? 1 : 0) + (result2 ? 1 : 0) + (result3 ? 1 : 0) + (result4 ? 1 : 0);

System.out.println(sum);
}
}


#Tasks
По-любому у каждого так😉

https://t.me/Java_for_beginner_dev

#Mems
Многопоточность в Java: ExecutorService

ExecutorService — это интерфейс, который предоставляет методы для управления жизненным циклом потоков и для выполнения задач. Он является частью фреймворка java.util.concurrent и предоставляет гибкие способы работы с потоками.


Основные методы ExecutorService

submit(Runnable task): Отправляет задачу на выполнение и возвращает объект Future, представляющий эту задачу.
submit(Callable<T> task): Отправляет задачу, возвращающую результат, на выполнение и возвращает объект Future.
invokeAll(Collection<? extends Callable<T>> tasks): Выполняет все задачи из коллекции и возвращает список объектов Future.
invokeAny(Collection<? extends Callable<T>> tasks): Выполняет все задачи из коллекции и возвращает результат одной из успешно завершенных задач.
shutdown(): Начинает плавное завершение работы пула, позволяя выполнению текущих задач завершиться.
shutdownNow(): Пытается немедленно завершить выполнение всех задач.


Пример использования submit
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

public class SubmitExample {

public static void main(String[] args) {
ExecutorService executorService = Executors.newFixedThreadPool(2);

Callable<Integer> task1 = () -> {
Thread.sleep(1000);
return 10;
};

Callable<Integer> task2 = () -> {
Thread.sleep(2000);
return 20;
};

Future<Integer> future1 = executorService.submit(task1);
Future<Integer> future2 = executorService.submit(task2);

try {
System.out.println("Result of task1: " + future1.get());
System.out.println("Result of task2: " + future2.get());
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}

executorService.shutdown();
}
}


Пример использования invokeAll и invokeAny
public class InvokeExample {

public static void main(String[] args) {
ExecutorService executorService = Executors.newFixedThreadPool(3);

List<Callable<Integer>> tasks = Arrays.asList(
() -> {
Thread.sleep(1000);
return 1;
},
() -> {
Thread.sleep(2000);
return 2;
},
() -> {
Thread.sleep(3000);
return 3;
}
);

try {
List<Future<Integer>> results = executorService.invokeAll(tasks);
for (Future<Integer> result : results) {
System.out.println("Result: " + result.get());
}

Integer anyResult = executorService.invokeAny(tasks);
System.out.println("First completed task result: " + anyResult);
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}

executorService.shutdown();
}
}


Управление завершением ExecutorService

Правильное завершение ExecutorService важно для предотвращения утечек ресурсов и корректного завершения программы.

shutdown(): Начинает плавное завершение. Новые задачи не принимаются, но уже отправленные задачи продолжают выполнение.
executorService.shutdown();


shutdownNow(): Пытается немедленно завершить все задачи, возвращает список задач, которые не были начаты.
List<Runnable> notExecutedTasks = executorService.shutdownNow();


awaitTermination(long timeout, TimeUnit unit): Ожидает завершения всех задач в течение указанного времени.

try {
if (!executorService.awaitTermination(60, TimeUnit.SECONDS)) {
executorService.shutdownNow();
}
} catch (InterruptedException e) {
executorService.shutdownNow();
}


#Java #Training #Multithreading #Medium #ExecutorService
Concurrency

Concurrency (параллельность) — это способность программы выполнять несколько задач одновременно. В контексте Java, это включает использование многопоточности и синхронизации для обеспечения корректного выполнения параллельных операций.

Коллекции и многопоточность

Стандартные коллекции, такие как ArrayList, HashMap, HashSet и другие, не являются потокобезопасными. Это означает, что если несколько потоков одновременно выполняют операции чтения и записи с этими коллекциями, могут возникнуть проблемы, такие как:


Несогласованность данных: Данные могут быть повреждены или потеряны.
Исключения времени выполнения: Например, ConcurrentModificationException.

Для решения этих проблем в Java были введены потокобезопасные коллекции из пакета java.util.concurrent.

ConcurrentHashMap — это потокобезопасная реализация HashMap, которая позволяет нескольким потокам одновременно выполнять операции чтения и записи. В отличие от синхронизированного HashMap, ConcurrentHashMap использует механизм сегментации (локов), что позволяет повысить производительность за счет уменьшения количества блокировок.

Пример использования ConcurrentHashMap
import java.util.concurrent.ConcurrentHashMap;

public class ConcurrentHashMapExample {

public static void main(String[] args) {
ConcurrentHashMap<String, Integer> concurrentMap = new ConcurrentHashMap<>();

// Добавление элементов в карту
concurrentMap.put("One", 1);
concurrentMap.put("Two", 2);
concurrentMap.put("Three", 3);

// Создание потоков для параллельного чтения и записи
Thread writerThread = new Thread(() -> {
for (int i = 4; i <= 6; i++) {
concurrentMap.put("Number " + i, i);
System.out.println("Added: Number " + i);
try {
Thread.sleep(100); // Симуляция задержки
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});

Thread readerThread = new Thread(() -> {
for (int i = 1; i <= 6; i++) {
System.out.println("Value for Number " + i + ": " + concurrentMap.get("Number " + i));
try {
Thread.sleep(150); // Симуляция задержки
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});

writerThread.start();
readerThread.start();

try {
writerThread.join();
readerThread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}


В этом примере ConcurrentHashMap используется для параллельных операций чтения и записи. Поток writerThread добавляет элементы в карту, в то время как поток readerThread считывает значения из карты. Благодаря использованию ConcurrentHashMap данные остаются согласованными, и исключения времени выполнения не возникают.

Основные методы ConcurrentHashMap

put(K key, V value): Добавляет пару ключ-значение в карту.
get(Object key): Возвращает значение, связанное с указанным ключом.
remove(Object key): Удаляет пару ключ-значение из карты.
replace(K key, V value): Заменяет значение, связанное с указанным ключом, на новое значение.
computeIfAbsent(K key, Function<? super K, ? extends V> mappingFunction): Если ключ отсутствует в карте, вычисляет значение и добавляет его в карту.


#Java #Training #Multithreading #Medium
Что выведет код?

public class AlgorithmChallenge {
public static void main(String[] args) {
int[] arr = {5, 3, 8, 6, 2};
int result = mysteriousFunction(arr);
System.out.println(result);
}

public static int mysteriousFunction(int[] arr) {
int n = arr.length;
int sum = 0;
for (int i = 0; i < n; i++) {
for (int j = i + 1; j < n; j++) {
if (arr[i] > arr[j]) {
sum += arr[i] - arr[j];
}
}
}
return sum;
}
}


#Tasks
Варианты ответа:
Anonymous Quiz
0%
3
10%
7
10%
21
80%
18
0%
25
Просто ChatGPT не дали доступ к оружию🙈

https://t.me/Java_for_beginner_dev

#Mems
Продвинутые методы ConcurrentHashMap

ConcurrentHashMap предоставляет дополнительные методы для более тонкого управления данными и выполнения атомарных операций.

Пример использования computeIfAbsent
import java.util.concurrent.ConcurrentHashMap;

public class ComputeIfAbsentExample {

public static void main(String[] args) {
ConcurrentHashMap<String, Integer> concurrentMap = new ConcurrentHashMap<>();

// Добавление элементов в карту
concurrentMap.put("One", 1);
concurrentMap.put("Two", 2);

// Использование computeIfAbsent для добавления значения, если ключ отсутствует
concurrentMap.computeIfAbsent("Three", key -> 3);
concurrentMap.computeIfAbsent("One", key -> 10); // Это значение не будет добавлено, так как ключ уже существует

System.out.println(concurrentMap); // {One=1, Two=2, Three=3}
}
}


Использование forEach и reduce

ConcurrentHashMap поддерживает методы для параллельной обработки данных, такие как forEach и reduce.

Пример использования forEach

import java.util.concurrent.ConcurrentHashMap;
import java.util.function.BiConsumer;

public class ForEachExample {

public static void main(String[] args) {
ConcurrentHashMap<String, Integer> concurrentMap = new ConcurrentHashMap<>();
concurrentMap.put("One", 1);
concurrentMap.put("Two", 2);
concurrentMap.put("Three", 3);

// Параллельная обработка элементов карты
concurrentMap.forEach(1, (key, value) -> {
System.out.println("Key: " + key + ", Value: " + value);
});
}
}


Пример использования reduce
import java.util.concurrent.ConcurrentHashMap;

public class ReduceExample {

public static void main(String[] args) {
ConcurrentHashMap<String, Integer> concurrentMap = new ConcurrentHashMap<>();
concurrentMap.put("One", 1);
concurrentMap.put("Two", 2);
concurrentMap.put("Three", 3);

// Параллельное суммирование значений карты
int sum = concurrentMap.reduceValues(1, Integer::sum);
System.out.println("Sum of values: " + sum); // Output: Sum of values: 6
}
}


Примеры использования ConcurrentHashMap в реальных задачах

Пример 1: Подсчет количества слов
import java.util.concurrent.ConcurrentHashMap;

public class WordCountExample {

public static void main(String[] args) {
ConcurrentHashMap<String, Integer> wordCounts = new ConcurrentHashMap<>();
String[] words = {"apple", "banana", "apple", "orange", "banana", "apple"};

for (String word : words) {
wordCounts.merge(word, 1, Integer::sum);
}

System.out.println(wordCounts); // {apple=3, banana=2, orange=1}
}
}


Пример 2: Кэширование вычислений
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Function;

public class ComputationCacheExample {

private final ConcurrentHashMap<Integer, String> cache = new ConcurrentHashMap<>();

public String compute(Integer key, Function<Integer, String> computation) {
return cache.computeIfAbsent(key, computation);
}

public static void main(String[] args) {
ComputationCacheExample example = new ComputationCacheExample();

Function<Integer, String> computation = key -> {
try {
Thread.sleep(1000); // Симуляция долгого вычисления
} catch (InterruptedException e) {
e.printStackTrace();
}
return "Result for " + key;
};

System.out.println(example.compute(1, computation)); // Вычисление и кэширование
System.out.println(example.compute(1, computation)); // Использование закэшированного значения
}
}


#Java #Training #Multithreading #Medium
Аннотации в Java

Аннотации в Java — это метаданные, которые добавляются к коду для предоставления дополнительной информации. Они могут быть использованы компилятором, инструментами разработки и во время выполнения (через рефлексию). Аннотации не изменяют логики программы, но могут влиять на её поведение.

Основные встроенные аннотации

@ Override: Указывает, что метод переопределяет метод суперкласса.
@ Deprecated: Обозначает, что элемент (метод, класс, поле) устарел и не рекомендуется к использованию.
@ SuppressWarnings: Подавляет указанные предупреждения компилятора.
@ SafeVarargs: Обозначает, что метод с переменным числом аргументов не выполняет потенциально небезопасных операций с varargs.
@ FunctionalInterface: Указывает, что интерфейс является функциональным и содержит только один абстрактный метод.


Примеры использования встроенных аннотаций
public class AnnotationExample {

@Override
public String toString() {
return "AnnotationExample";
}

@Deprecated
public void oldMethod() {
System.out.println("This method is deprecated");
}

@SuppressWarnings("unchecked")
public void uncheckedOperation() {
List rawList = new ArrayList();
rawList.add("String");
}

@SafeVarargs
public final void safeVarargsMethod(List<String>... lists) {
for (List<String> list : lists) {
System.out.println(list);
}
}

@FunctionalInterface
interface MyFunctionalInterface {
void execute();
}
}


Методы аннотаций

Аннотации могут содержать методы. Методы аннотаций могут иметь значения по умолчанию.
@interface MyAnnotation {
String value();
int number() default 42;
}


Аннотацию можно использовать с параметрами:
@MyAnnotation(value = "Example", number = 10)
public class AnnotatedClass {
}


Аннотации и рефлексия

Аннотации можно считывать во время выполнения с помощью рефлексии. Это позволяет динамически изменять поведение программы в зависимости от аннотированных элементов.


Пример использования рефлексии для чтения аннотаций

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;

public class ReflectionExample {

@MyAnnotation(value = "Test", number = 5)
public void annotatedMethod() {
}

public static void main(String[] args) throws Exception {
Method method = ReflectionExample.class.getMethod("annotatedMethod");

if (method.isAnnotationPresent(MyAnnotation.class)) {
MyAnnotation annotation = method.getAnnotation(MyAnnotation.class);
System.out.println("Value: " + annotation.value());
System.out.println("Number: " + annotation.number());
}
}
}


#Java #Training #Annotation #Medium
Что выведет код?

public class ConcatChallenge {
public static void main(String[] args) {
String[] arr = {"Java", "is", "fun"};
String result = mysteriousConcat(arr);
System.out.println(result);
}

public static String mysteriousConcat(String[] arr) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < arr.length; i++) {
sb.append(arr[i]);
if (i < arr.length - 1) {
sb.append("-");
}
}
return sb.toString();
}
}


#Tasks
Варианты ответа:
Anonymous Quiz
0%
Java-isfun
0%
Javais-fun
88%
Java-is-fun
13%
Javaisfun
Злободневно🤪😂

https://t.me/Java_for_beginner_dev

#Mems
Создание собственных аннотаций в Java

Создание собственных аннотаций позволяет добавлять метаданные к вашему коду, которые могут быть использованы компилятором, инструментами разработки или во время выполнения. Аннотации можно использовать для валидации данных, конфигурации и других задач.

Для создания аннотации используется ключевое слово @ interface.
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

@Retention(RetentionPolicy.RUNTIME)
public @interface MyCustomAnnotation {
String value();
int number() default 42;
}


@ Retention: Указывает, насколько долго аннотация сохраняется (например, только в исходном коде, в классе или во время выполнения).
RetentionPolicy.SOURCE: Аннотация сохраняется только в исходном коде и отбрасывается компилятором.
RetentionPolicy.CLASS: Аннотация сохраняется в файле класса, но не доступна во время выполнения.
RetentionPolicy.RUNTIME: Аннотация сохраняется во время выполнения и может быть прочитана с помощью рефлексии.


Применение собственной аннотации
@MyCustomAnnotation(value = "Example", number = 10)
public class CustomAnnotatedClass {
}


Чтение аннотаций с помощью рефлексии
import java.lang.annotation.Annotation;

public class CustomAnnotationReflection {

public static void main(String[] args) {
Class<CustomAnnotatedClass> clazz = CustomAnnotatedClass.class;

if (clazz.isAnnotationPresent(MyCustomAnnotation.class)) {
MyCustomAnnotation annotation = clazz.getAnnotation(MyCustomAnnotation.class);
System.out.println("Value: " + annotation.value());
System.out.println("Number: " + annotation.number());
}
}
}


Методы аннотаций

Аннотации могут содержать методы, которые определяют параметры аннотации. Методы могут иметь значения по умолчанию.
public @interface DetailedAnnotation {
String description();
boolean enabled() default true;
}


Пример использования:
@DetailedAnnotation(description = "This is a detailed annotation", enabled = false)
public class DetailedAnnotatedClass {
}


Ограничения и мета-аннотации

Мета-аннотации — это аннотации, которые применяются к другим аннотациям. В Java существует несколько мета-аннотаций:

@ Retention:
Указывает, насколько долго аннотация сохраняется.
@ Target: Указывает, где аннотация может быть применена (например, к методам, полям, классам).
@ Inherited: Указывает, что аннотация может быть унаследована подклассами.
@ Documented: Указывает, что аннотация должна быть задокументирована с помощью javadoc.


Пример использования мета-аннотаций:
import java.lang.annotation.ElementType;
import java.lang.annotation.Target;

@Target({ElementType.TYPE, ElementType.METHOD})
public @interface MultiTargetAnnotation {
String value();
}


Пример практического использования собственных аннотаций

Валидация с помощью аннотаций


Создадим аннотацию для проверки полей класса:
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface NotNull {
}
Применим аннотацию к классу:

java
Копировать код
public class User {
@NotNull
private String name;

public User(String name) {
this.name = name;
}
}

#Java #Training #Annotation #Medium
Создадим метод для проверки полей:
import java.lang.reflect.Field;

public class Validator {

public static void validate(Object object) throws IllegalAccessException {
Field[] fields = object.getClass().getDeclaredFields();
for (Field field : fields) {
if (field.isAnnotationPresent(NotNull.class)) {
field.setAccessible(true);
Object value = field.get(object);
if (value == null) {
throw new IllegalArgumentException(field.getName() + " cannot be null");
}
}
}
}

public static void main(String[] args) {
User user = new User(null);
try {
validate(user);
} catch (IllegalArgumentException | IllegalAccessException e) {
e.printStackTrace();
}
}
}

Этот пример показывает, как создавать и использовать собственные аннотации для выполнения валидации данных. Аннотации делают код более читаемым и структурированным, позволяя легко добавлять новые проверки и конфигурации.

#Java #Training #Annotation #Medium
Всем доброго субботнего утра! ☀️

Как ваше настроение, какие планы на выходные?
Делитесь с нами в чате -
https://t.me/Java_Beginner_chat

Напоминаю, что завтра в 16:00 по МСК запланирована онлайн встреча, где мы наконец-то закончим наше консольное TODO приложение!)))
Утро программиста.

объекты: Жена, Будильник, Автомобиль;
переменные: совесть, желание_спать, сытость, злость

если Будильник = 1
{
перевести(5min);
перевести(5min);
выключить();
встать();
}

если Будильник = 0
{

пока (совесть < желание_спать)
{
спать();
}

встать();
}

умыться();

если Жена > 0
{
приготовить_завтрак(жена);
}

если Жена = 0
{
приготовить_завтрак(содержимое холодильника[0]);
}

сытость = сытость + 1;

если автомобиль !=1
{
добраться_до_работы(спать());
}

если автомобиль =1
{
добраться_до_работы(злость);
}


#Mems
Напоминаю про канал моего товарища 3D-шника) - https://t.me/model3ddd/3511

Если вас интересует данная тема, есть желание изучить ее подробнее, ознакомиться с примерами работ - залетайте не думая!
А вы придете на онлайн встречу в 16:00 по МСК сегодня?
Anonymous Poll
42%
Да, я буду!)
50%
Хотел бы, но не могу(
0%
Нет, нафиг мне это надо?)))
8%
Что это за канал?)