Источник: MediumСодержание этой публикации посвящено примитивным типам данных в Java, их преимуществам и вариантам применения в разработке.В Java существует восемь примитивных типов данных, которые можно использовать для представления различных типов данных. Давайте рассмотрим каждый из них на конкретных примерах их использования.
boolean
Тип данных boolean (размер 8 бит) используется для представления двух возможных значений: true или false. Обычно он применяется в условных операторах, циклах и других логических операциях. Пример кода:
Тип данных byte (размер 8 бит) используется для представления целых чисел от -128 до 127. Этот тип данных часто используется для небольших целочисленных значений, особенно при работе с потоками данных. Пример кода:
byte myByte = 10;
short
Тип данных short (размер 16 бит) используется для представления целых чисел от -32 768 до 32 767. Этот тип данных используется для целочисленных значений, для которых требуется больший диапазон, чем может предоставить byte, но меньше, чем может предоставить int. Пример кода:
short temperature = -20;
int
Тип данных int (размер 32 бит) используется для представления целых чисел от -2 147 483 648 до 2 147 483 647. Этот тип данных обычно используется для целочисленных значений, которые не требуют большого диапазона или высокой точности. В языке Java int является типом данных по умолчанию для целочисленных значений. Пример кода:
int age = 25;
int quantity = 10;
long
Тип данных long (размер 64 байта) используется для представления целых чисел от -9 223 372 036 854 775 808 до 9 223 372 036 854 775 807. Этот тип данных используется для целочисленных значений, для которых требуется еще более широкий диапазон, чем может предоставить int. Тип данных long следует использовать, когда int уже недостаточен для представления требуемых значений. Пример кода:
long population = 7_594_000_000L;
long distanceToSun = 149_600_000L;
Обратите внимание, что символ L в конце числа указывает на то, что значение является long.
float
Тип данных float (размер 32 байта) используется для представления десятичных чисел с диапазоном примерно от -3,4E38 до 3,4E38 и точностью в 6-7 цифр. Этот тип данных используется для значений, которые требуют меньшей точности, чем та, что обеспечивает double, или когда размер памяти ограничен. Пример кода:
float weight = 65.5f;
float temperature = 25.7f;
Обратите внимание, что символ f в конце числа указывает на то, что значение является float.
double
Тип данных double (размер 64 байта) используется для представления десятичных чисел с более высокой точностью, чем может обеспечить float. Этот тип данных обычно используется для научных и математических расчетов, требующих высокой точности. Пример кода:
double pi = 3.141592653589793;
double e = 2.718281828459045;
char
Тип данных char (размер 16 байт) используется для представления одного символа. Учтите, что в Java символы отображаются в кодировке Unicode. Пример кода:
char firstLetter = 'a';
char lastLetter = 'z';
Значения по умолчанию
В Java, если примитивный тип данных объявлен как переменная экземпляра, то ему будет автоматически присвоено значение по умолчанию (default). Справа от каждого примитивного типа данных можно увидеть его значение по умолчанию:
boolean: false
byte: 0
short: 0
int: 0
long: 0L
float: 0.0f
double: 0.0d
char: \u0000 (null character)
Помните, что вам нет необходимости присваивать примитивному типу данных значение по умолчанию, поскольку Java сделает это автоматически.
Заключение
Выбор правильного типа данных в Java важен для эффективного использования памяти и точных вычислений. Используйте boolean для логических значений, byte для небольших целых значений, short для целых значений с немного большим диапазоном и int для целых значений, которые не требуют высокой точности.
Пакеты и интерфейсы, входящие в Java Concurrent API
Источник: MediumЭто руководство включает в себя подробную информацию об основных пакетах и интерфейсах, входящих в Java Concurrent API.
Библиотека Java Concurrency обеспечивает основу для разработки многопоточных параллельных программ и включает в себя различные высокоуровневые функции параллелизма. Перед вами некоторые из основных пакетов Java Concurrent API и их описания:
java.util.concurrent
java.util.concurrent — это основной пакет Java Concurrent API. Он включает в себя несколько классов, которые используются для параллельного программирования. В этот список входит:
ExecutorService — интерфейс, представляющий механизм асинхронного выполнения, способный одновременно выполнять задачи в фоновом режиме.
Future<V> — представляет результат асинхронного вычисления.
ScheduledExecutorService — это расширенный вариант ExecutorService, который может планировать запуск команд после заданной задержки или периодически.
CountDownLatch — средство синхронизации, которое позволяет одному или нескольким потокам ожидать завершения набора операций, выполняемых в других потоках.
java.util.concurrent.atomic
java.util.concurrent.atomic — этот пакет определяет классы, поддерживающие атомарные операции, то есть операции, выполняемые как единая единица работы без возможности вмешательства других операций.
AtomicInteger, AtomicLong, AtomicBoolean и так далее — эти классы обеспечивают атомарные (то есть потокобезопасные) операции над отдельными переменными, такие как операции увеличения и уменьшения.
AtomicReference<V> — предоставляет атомарную ссылку на объект, который может быть обновлен атомарно.
java.util.concurrent.locks
java.util.concurrent.locks — этот пакет предоставляет структуру интерфейсов и классов для блокировки и ожидания условий более гибким способом, чем с синхронизированными методами и операторами.
ReentrantLock — блокировка взаимного исключения с повторным входом с тем же базовым поведением, что и неявные мониторы, доступ к которым осуществляется с помощью методов synchronized и операторов, но с расширенными возможностями.
ConditionObject — методы монитора (wait, notify и notifyAll), разделенные на отдельные объекты для обеспечения более точной блокировки и ожидания.
java.util.concurrent.Future
java.util.concurrent.Future — это интерфейс Future, который представляет будущий результат асинхронного вычисления — результат, который в конечном итоге появится в Future после завершения вычисления.
java.util.concurrent.BlockingQueue
java.util.concurrent.BlockingQueue — это интерфейс BlockingQueue, представляющий собой очередь, которая является потокобезопасной для размещения и получения экземпляров. BlockingQueue заблокируется, если вы попытаетесь получить экземпляр, пока очередь пуста, или если вы попытаетесь разместить его, когда очередь заполнена.
Эти пакеты и классы используются для создания потоков и управления ими, обработки взаимодействия между потоками, синхронизации и других расширенных концепций параллелизма в Java. Правильное использование Concurrent API может значительно упростить разработку многопоточных приложений на Java.
Вот простой пример, демонстрирующий использование ExecutorService и Future из пакета java.util.concurrent. В этом примере запускается пул потоков, назначаются им задачи, а затем извлекаются результаты этих задач.
import java.util.concurrent.*;
public class ConcurrentApiExample {
public static void main(String[] args) throws ExecutionException, InterruptedException {
ExecutorService executorService = Executors.newFixedThreadPool(5); // создаем пул потоков с 5 потоками
// задача Callable, возвращающая квадрат целого числа
Callable<Integer> callableTask = new Callable<Integer>() {
@Override
public Integer call() {
int value = ThreadLocalRandom.current().nextInt(1, 10);
int square = value * value;
System.out.println("The square of " + value + " is: " + square);
return square;
}
};
Future<Integer>[] futures = new Future[5]; // массив для хранения будущих объектов
for(int i = 0; i < 5; i++){
futures[i] = executorService.submit(callableTask); // отправляем задачу на выполнение пулом потоков
}
for(int i = 0; i < 5; i++){
Integer result = futures[i].get(); // получаем результат вычисления
System.out.println("The result of the computation is: " + result);
}
executorService.shutdown(); // отключаем службу-исполнитель
}
}
В данном примере мы создаем ExecutorService с фиксированным пулом потоков размером 5. Затем мы создаем задачу Callable, которая возвращает квадрат случайного целого числа. Мы пять раз отправляем эту задачу в службу-исполнитель и собираем объекты Future. Затем мы извлекаем результаты из объектов Future с помощью метода get. И наконец, мы отключаем службу-исполнитель.
Обратите внимание, что в этом примере используется ThreadLocalRandom — параллельная утилита для генерации случайных чисел в многопоточных средах.
Также учтите, что на практике рекомендуется использовать блоки try-catch при работе с потоками для обработки любых потенциальных ошибок InterruptedExceptions или ExecutionExceptions.
Та нет, ты кое-что очень сильно не учел, но ничего, всему свое время.
Насчет шорта, в целом конечно мы используем int для целочисленных значений и не паримся, но у шорта тоже есть юзкейсы, когда мы хотим использовать компилятор и строгую типизацию и явно ограничить диапазон значений для переменных, в embedded где каждый байт может быть критично тоже может использоваться, в портировании кода и тд.
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ