История технологии сегодня — 2 июля
ℹ️ Кто родился в этот день
Па́вел Дми́триевич Кузьми́нский (20 июня [2 июля] 1840, Усть-Лабинская, Кубанская область — 7 [20] апреля 1900, Санкт-Петербург) — русский инженер, изобретатель газовой турбины.
Ханс А́льбрехт Бе́те (нем. Hans Albrecht Bethe; 2 июля 1906 года, Страсбург, Германия — 6 марта 2005 года, Итака, Нью-Йорк) — американский астрофизик и физик-ядерщик, лауреат Нобелевской премии по физике (1967). В сферу его интересов также входили квантовая электродинамика и физика твёрдого тела.
🌐 Знаковые события
1948 — первый полёт летающей лодки Бе-6.
#Biography #Birth_Date #Events #02июля
Па́вел Дми́триевич Кузьми́нский (20 июня [2 июля] 1840, Усть-Лабинская, Кубанская область — 7 [20] апреля 1900, Санкт-Петербург) — русский инженер, изобретатель газовой турбины.
Ханс А́льбрехт Бе́те (нем. Hans Albrecht Bethe; 2 июля 1906 года, Страсбург, Германия — 6 марта 2005 года, Итака, Нью-Йорк) — американский астрофизик и физик-ядерщик, лауреат Нобелевской премии по физике (1967). В сферу его интересов также входили квантовая электродинамика и физика твёрдого тела.
1948 — первый полёт летающей лодки Бе-6.
#Biography #Birth_Date #Events #02июля
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3
[Совет по Java #056]
Тема:
Проблема:
Однако он не предоставляет сами результаты. Разработчики часто ошибочно полагают, что результирующий фьючер содержит список значений, и пытаются его обработать, сталкиваясь с тем, что нет доступа к данным. Приходится либо повторно обращаться к исходным фьючерам через
Решение: После
Важно помнить, что
Объяснение:
Передавая массив фьючеров, мы получаем
После того как
#Java #советы
Тема:
CompletableFuture.allOf не возвращает результаты.Проблема:
CompletableFuture.allOf(CompletableFuture<?>... cfs) возвращает CompletableFuture<Void>, который завершается, когда все переданные фьючеры завершены (успешно или с исключением). Однако он не предоставляет сами результаты. Разработчики часто ошибочно полагают, что результирующий фьючер содержит список значений, и пытаются его обработать, сталкиваясь с тем, что нет доступа к данным. Приходится либо повторно обращаться к исходным фьючерам через
join(), либо использовать громоздкие конструкции. Это ведет к дублированию кода и потенциальным ошибкам, если какой-то фьючер завершился исключительно.Решение: После
allOf примените thenApply или thenRun, чтобы объединить результаты из исходного списка. Самый чистый способ — обернуть allOf в цепочку, которая собирает значения через Stream и map(CompletableFuture::join). Если нужна обработка каждого результата, используйте thenApply с преобразованием в коллекцию. Для асинхронного продолжения можно применить thenCompose или thenCombine, но они сложнее. Важно помнить, что
join() на завершенном фьючере не блокирует (или блокирует очень коротко), поэтому безопасно вызывать его после allOf.import java.util.concurrent.CompletableFuture;
import java.util.List;
import java.util.stream.Collectors;
public class AllOfResults {
public static void main(String[] args) {
List<CompletableFuture<String>> futures = List.of(
CompletableFuture.supplyAsync(() -> "Result 1"),
CompletableFuture.supplyAsync(() -> "Result 2"),
CompletableFuture.supplyAsync(() -> "Result 3")
);
//allOf возвращает Void — результаты не доступны
CompletableFuture<Void> all = CompletableFuture.allOf(futures.toArray(new CompletableFuture[0]));
all.join(); // ждем завершения, но результатов нет
//Собираем результаты вручную через thenApply
CompletableFuture<List<String>> combined = CompletableFuture
.allOf(futures.toArray(new CompletableFuture[0]))
.thenApply(v -> futures.stream()
.map(CompletableFuture::join)
.collect(Collectors.toList()));
List<String> results = combined.join();
System.out.println(results); // [Result 1, Result 2, Result 3]
// ✅ Альтернатива: использование thenAccept для побочного эффекта
CompletableFuture<Void> log = CompletableFuture
.allOf(futures.toArray(new CompletableFuture[0]))
.thenAccept(v -> futures.forEach(f -> System.out.println(f.join())));
log.join();
//Сборка с преобразованием типов
CompletableFuture<Integer> totalLength = CompletableFuture
.allOf(futures.toArray(new CompletableFuture[0]))
.thenApply(v -> futures.stream()
.map(CompletableFuture::join)
.mapToInt(String::length)
.sum());
System.out.println("Total length: " + totalLength.join());
}
}
Объяснение:
allOf — это синхронизатор, а не коллектор. Его предназначение — дождаться завершения всех задач, чтобы затем предпринять действие. Передавая массив фьючеров, мы получаем
Void, потому что при проектировании API было решено не навязывать типовые ограничения на разнородные результаты. Поэтому сбор результатов остается на совести разработчика. После того как
allOf завершился, все фьючеры гарантированно находятся в состоянии "завершено" (completed), поэтому вызов join() на каждом из них не блокирует и безопасен. Это позволяет строить цепочки, где thenApply получает Void и возвращает нужную коллекцию. Для обработки ошибок используйте handle вместо thenApply. #Java #советы
👍5
Что выведет код?
#Tasks
import java.util.concurrent.CompletableFuture;
public class Task020726 {
public static void main(String[] args) throws Exception {
CompletableFuture<Integer> f1 = CompletableFuture.completedFuture(42);
CompletableFuture<String> f2 = CompletableFuture.completedFuture("hello");
CompletableFuture<Void> all = CompletableFuture.allOf(f1, f2);
System.out.println(all.get());
}
}
#Tasks
👍4
👍4
Что такое 🤓
Ответ:
Методы copyOf() (Java 10) создают неизменяемую (immutable) копию коллекции.
Если исходная коллекция уже неизменяема, метод может вернуть её же. Бросают NullPointerException, если коллекция содержит null.
Это часть новой стратегии создания неизменяемых коллекций. Также в Java 9 появились фабричные методы: List.of(), Set.of(), Map.of() для создания компактных неизменяемых коллекций.
Это упрощает инициализацию и гарантирует потокобезопасность (коллекции не изменяются).
#собеседование
List.copyOf(), Set.copyOf(), Map.copyOf()? Ответ:
Если исходная коллекция уже неизменяема, метод может вернуть её же. Бросают NullPointerException, если коллекция содержит null.
Это часть новой стратегии создания неизменяемых коллекций. Также в Java 9 появились фабричные методы: List.of(), Set.of(), Map.of() для создания компактных неизменяемых коллекций.
Это упрощает инициализацию и гарантирует потокобезопасность (коллекции не изменяются).
#собеседование
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5
История технологии сегодня — 3 июля
ℹ️ Кто родился в этот день
Леонид Александрович Шеметков (бел. Леанід Аляксандравіч Шамяткоў; 3 июля 1937, Гомель — 24 марта 2013, Гомель) — белорусский математик. Тематика научных исследований Леонида Александровича связана преимущественно с теорией конечных групп, которая, по высказыванию его учителя С. А. Чунихина, является «трамплином и творческой лабораторией для алгебры в целом». В 1947 г. ленинградский математик, член-корреспондент АН СССР Д. К. Фаддеев установил принципиальную возможность описания конечных недисперсивных разрешимых групп порядка pnq и поставил задачу о справедливости этого результата для разрешимых групп произвольного порядка.
Джесси Дуглас (англ. Jesse Douglas; 3 июля 1897 — 7 сентября 1965) — американский математик, лауреат Филдсовской премии 1936 года. Джесси Дуглас также внёс значительный вклад в решение обратной задачи Лагранжевой механики. В 1943 году Американское математическое общество присудило ему премию имени М. Бохера.
🌐 Знаковые события
1958 — начались ходовые испытания первой советской атомной подводной лодки К-3 «Ленинский комсомол».
2006 — астероид 2004 XP14 пролетел на расстоянии 432 308 километров от поверхности Земли.
#Biography #Birth_Date #Events #03июля
Леонид Александрович Шеметков (бел. Леанід Аляксандравіч Шамяткоў; 3 июля 1937, Гомель — 24 марта 2013, Гомель) — белорусский математик. Тематика научных исследований Леонида Александровича связана преимущественно с теорией конечных групп, которая, по высказыванию его учителя С. А. Чунихина, является «трамплином и творческой лабораторией для алгебры в целом». В 1947 г. ленинградский математик, член-корреспондент АН СССР Д. К. Фаддеев установил принципиальную возможность описания конечных недисперсивных разрешимых групп порядка pnq и поставил задачу о справедливости этого результата для разрешимых групп произвольного порядка.
Джесси Дуглас (англ. Jesse Douglas; 3 июля 1897 — 7 сентября 1965) — американский математик, лауреат Филдсовской премии 1936 года. Джесси Дуглас также внёс значительный вклад в решение обратной задачи Лагранжевой механики. В 1943 году Американское математическое общество присудило ему премию имени М. Бохера.
1958 — начались ходовые испытания первой советской атомной подводной лодки К-3 «Ленинский комсомол».
2006 — астероид 2004 XP14 пролетел на расстоянии 432 308 километров от поверхности Земли.
#Biography #Birth_Date #Events #03июля
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2
Раздел 11. Работа с файлами, I/O и сетью (NIO.2)
Глава 1. Классический Java I/O (java.io)
Практика: Написать утилиту копирования файлов
Архитектура
Утилита копирует файл из источника в назначение тремя способами: побайтово, с внешним массивом-буфером, и с
Путь данных: общая схема
Классы и их ответственность
Три реализации:
Архитектура копирования директории
Путь данных для каждой стратегии
Побайтовое копирование
Память: нет массивов в heap. Проблема: 2 * fileSize системных вызовов. Для 100MB: 209 715 200 вызовов.
Копирование с внешним буфером
Память:
Копирование с BufferedInputStream/BufferedOutputStream
Память:
Закрытие ресурсов
Ожидаемые результаты замеров (100MB файл, SSD)
Структура проекта
Ключевые моменты для реализации
Глава 1. Классический Java I/O (java.io)
Практика: Написать утилиту копирования файлов
Архитектура
Утилита копирует файл из источника в назначение тремя способами: побайтово, с внешним массивом-буфером, и с
BufferedInputStream/BufferedOutputStream. Замеряет время каждого способа. Поддерживает копирование нескольких файлов в директорию. Опционально определяет тип файла по первым 16 байтам через PushbackInputStream.Путь данных: общая схема
[Источник: файл на диске]
-> [Page Cache ОС]
-> [FileInputStream: syscall read()]
-> [Нативный буфер userspace]
-> [JNI: копирование в byte[] или напрямую в буфер JVM]
-> [Варианты обработки:]
-> [Способ 1: read() посимвольно -> write(int)]
-> [Способ 2: read(byte[]) -> write(byte[])]
-> [Способ 3: BufferedInputStream.read() -> BufferedOutputStream.write()]
-> [FileOutputStream: syscall write()]
-> [Нативный буфер userspace]
-> [Page Cache: dirty pages]
-> [Назначение: файл на диске]
Классы и их ответственность
FileCopyStrategy — интерфейс стратегии// Функциональный интерфейс для единообразия
@FunctionalInterface
public interface FileCopyStrategy {
void copy(InputStream source, OutputStream destination) throws IOException;
}
Три реализации:
ByteByByteCopy FileInputStream, FileOutputStream Каждый байт: syscall + копирование в нативный буфер + возврат int. Никаких массивов в heap.BufferedArrayCopy FileInputStream, FileOutputStream, byte[8192] Блок 8KB читается в массив heap, записывается из массива. Один syscall на блок.BufferedStreamCopy BufferedInputStream, BufferedOutputStream Внутренние буферы buf[8192] в heap каждого потока. Данные копируются между буферами без внешнего массива.FileTypeDetector — определение типа по сигнатуреpublic class FileTypeDetector {
// Сигнатуры: первые байты файла
private static final byte[] PNG_SIGNATURE = {(byte) 0x89, 0x50, 0x4E, 0x47};
private static final byte[] PDF_SIGNATURE = {0x25, 0x50, 0x44, 0x46};
private static final byte[] ZIP_SIGNATURE = {0x50, 0x4B, 0x03, 0x04};
public FileType detect(InputStream in) throws IOException {
// PushbackInputStream позволяет вернуть прочитанные байты обратно в поток
PushbackInputStream pis = new PushbackInputStream(in, 16);
byte[] header = new byte[16];
int read = pis.read(header);
pis.unread(header, 0, read); // Возврат байт в поток
// Определение типа по сигнатуре
if (matches(header, PNG_SIGNATURE)) return FileType.PNG;
if (matches(header, PDF_SIGNATURE)) return FileType.PDF;
if (matches(header, ZIP_SIGNATURE)) return FileType.ZIP;
return FileType.UNKNOWN;
}
}
PushbackInputStream — декоратор с внутренним буфером buf[pushbackSize]. При read() данные извлекаются из буфера отката, если он не пуст, иначе — из underlying потока. unread() помещает байты в буфер отката. Это позволяет «заглянуть» в поток без потери данных.FileCopyUtil — координатор операцийpublic class FileCopyUtil {
// Копирование одного файла с замером времени
public CopyResult copySingleFile(Path source, Path destination,
FileCopyStrategy strategy);
// Копирование нескольких файлов в директорию
public List<CopyResult> copyDirectory(Path sourceDir, Path targetDir,
FileCopyStrategy strategy);
// Копирование с определением типа
public TypedCopyResult copyWithTypeDetection(Path source, Path destination);
}
CopyResult — результат операцииpublic record CopyResult(
Path source,
Path destination,
long bytesCopied,
long durationMillis,
FileCopyStrategy strategy
) {}
Архитектура копирования директории
[sourceDir: директория]
-> [Files.list() / DirectoryStream: поток путей]
-> [Фильтрация: только обычные файлы]
-> [Для каждого файла:]
-> [Создание targetPath: targetDir.resolve(sourceDir.relativize(file))]
-> [Создание родительских директорий: Files.createDirectories()]
-> [Копирование файла через выбранную стратегию]
-> [Замер времени: System.nanoTime()]
Путь данных для каждой стратегии
Побайтовое копирование
[FileInputStream.read()] // syscall на каждый байт
-> [int в стеке]
-> [FileOutputStream.write(int)] // syscall на каждый байт
Память: нет массивов в heap. Проблема: 2 * fileSize системных вызовов. Для 100MB: 209 715 200 вызовов.
Копирование с внешним буфером
[FileInputStream.read(byte[8192])] // syscall на блок
-> [byte[8192] в heap]
-> [FileOutputStream.write(byte[8192], 0, len)] // syscall на блок
Память:
byte[8192] в Eden, создается один раз, переиспользуется. Системных вызовов: 2 * (100MB / 8KB) = 25 600.Копирование с BufferedInputStream/BufferedOutputStream
[BufferedInputStream.read()] // Без syscall, если данные в buf
-> [buf[8192] внутри BufferedInputStream]
-> [BufferedOutputStream.write(int)] // Накопление в buf
-> [При заполнении buf: syscall через underlying FileOutputStream]
Память:
buf[8192] в BufferedInputStream (16KB heap), buf[8192] в BufferedOutputStream (16KB heap). Внешний массив не нужен. Системных вызовов: ~25 600 чтений + ~25 600 записей.Закрытие ресурсов
// try-with-resources для всех потоков
public void copyWithResources(Path source, Path destination) throws IOException {
try (InputStream fis = new FileInputStream(source.toFile());
InputStream bis = new BufferedInputStream(fis); // опционально
OutputStream fos = new FileOutputStream(destination.toFile());
OutputStream bos = new BufferedOutputStream(fos)) { // опционально
// Копирование
}
// Все потоки закрыты в обратном порядке: bos, fos, bis, fis
}
Ожидаемые результаты замеров (100MB файл, SSD)
Структура проекта
src/
├── strategy/
│ ├── FileCopyStrategy.java
│ ├── ByteByByteCopy.java
│ ├── BufferedArrayCopy.java
│ └── BufferedStreamCopy.java
├── detector/
│ ├── FileType.java
│ └── FileTypeDetector.java
├── util/
│ ├── FileCopyUtil.java
│ └── CopyResult.java
└── Main.java
Ключевые моменты для реализации
Files.newInputStream() / Files.newOutputStream() — NIO.2 альтернатива классическим потокамFiles.copy() — стандартная утилита, использует transferTo() с zero-copySystem.nanoTime() — замер времени, не подвержен смещению часовFiles.createDirectories() — создание цепочки директорийPath.relativize() / Path.resolve() — манипуляция путями👍3🆒1
Что выведет код?
#Tasks
import java.util.stream.Stream;
public class Task030726 {
public static void main(String[] args) {
Stream<Integer> stream = Stream.of(1, 2, 3);
stream.forEach(System.out::print);
stream.forEach(System.out::print);
}
}
#Tasks
👍3
👍3
Какие новые методы появились в 🤓
Ответ:
В Java 9 добавлены:
Stream.iterate(T seed, Predicate hasNext, UnaryOperator next) — возможность задать условие остановки (усовершенствованный for-цикл).
takeWhile(Predicate) — берёт элементы, пока условие истинно, затем прерывает поток.
dropWhile(Predicate) — отбрасывает элементы, пока условие истинно, затем возвращает остаток.
Эти методы позволяют работать с бесконечными стримами и условными потоками без использования limit или filter с побочным эффектом. Они эффективны для частичной обработки потоков.
#собеседование
Stream API в Java 9? Ответ:
Stream.iterate(T seed, Predicate hasNext, UnaryOperator next) — возможность задать условие остановки (усовершенствованный for-цикл).
takeWhile(Predicate) — берёт элементы, пока условие истинно, затем прерывает поток.
dropWhile(Predicate) — отбрасывает элементы, пока условие истинно, затем возвращает остаток.
Эти методы позволяют работать с бесконечными стримами и условными потоками без использования limit или filter с побочным эффектом. Они эффективны для частичной обработки потоков.
#собеседование
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6
История технологии сегодня — 4 июля
ℹ️ Кто родился в этот день
Жан-Пьер Франсуа Бланшар (фр. Jean Pierre François Blanchard; 4 июля 1753 — 7 марта 1809) — французский изобретатель, наиболее известен как пионер воздухоплавания. Совершил свой первый успешный полёт на воздушном шаре 2 марта 1784 года в Париже, на заполненном водородом воздушном шаре на Марсовом поле.
🌐 Знаковые события
2012 — официально объявлено об открытии в ЦЕРНе новой частицы, по свойствам похожей на предсказанный бозон Хиггса.
#Biography #Birth_Date #Events #04июля
Жан-Пьер Франсуа Бланшар (фр. Jean Pierre François Blanchard; 4 июля 1753 — 7 марта 1809) — французский изобретатель, наиболее известен как пионер воздухоплавания. Совершил свой первый успешный полёт на воздушном шаре 2 марта 1784 года в Париже, на заполненном водородом воздушном шаре на Марсовом поле.
2012 — официально объявлено об открытии в ЦЕРНе новой частицы, по свойствам похожей на предсказанный бозон Хиггса.
#Biography #Birth_Date #Events #04июля
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥2👍1
Please open Telegram to view this post
VIEW IN TELEGRAM
🤣5🔥1
Please open Telegram to view this post
VIEW IN TELEGRAM
История технологии сегодня — 5 июля
ℹ️ Кто родился в этот день
Ю́рис Ха́ртманис (латыш. Juris Hartmanis; 5 июля 1928, Рига — 29 июля 2022) — учёный в области теории вычислительных систем, награждён в 1993 году премией Тьюринга за достижения в исследовании теории сложности вычислений.
Уильям Джон Макуорн Ранкин (Ренкин) (англ. William John Macquorn Rankine; 5 июля 1820, Эдинбург — 24 декабря 1872, Глазго) — шотландский инженер, физик и механик, один из создателей технической термодинамики. В 1849 году независимо от Клаузиуса получил общие уравнения термодинамики, выражающие соотношение между количеством теплоты и механической энергией. Исследовал термодинамические свойства газов и пара в 1850 году и составил таблицы водяных паров получивших широкое применение. В 1859 году построил полную теорию паровой машины; в частности, разработал идеальный термодинамический цикл парового двигателя, названного в его честь.
Ге́рард Хо́фт (Герард эт Хоофт, нид. Gerardus (Gerard) ’t Hooft; род. 5 июля 1946, Ден-Хелдер, Северная Голландия) — голландский физик-теоретик, профессор Утрехтского университета (Нидерланды), лауреат Нобелевской премии по физике за 1999 год (совместно с Мартинусом Велтманом). Разработанные Хофтом и Велтманом математические методы ренормализации янг-миллсовских полей, как безмассовых, так и получающих массу вследствие спонтанного нарушения симметрии, позволили рассчитать некоторые эффекты электрослабого взаимодействия, в частности, оценить массы промежуточных векторных бозонов W± и Z0, предсказанных теорией и вскоре после этого открытых экспериментально, причём полученные значения хорошо согласовывались с экспериментальными данными. Методом Велтмана и Хофта также была рассчитана масса топ-кварка, экспериментально обнаруженного в 1995 году в Национальной лаборатории им. Э. Ферми (США).
🌐 Знаковые события
1996 — в Великобритании родилось первое клонированное млекопитающее — овца Долли
2016 — автоматическая межпланетная станция НАСА «Юнона», запущенная в 2011 году, вышла на полярную орбиту Юпитера.
#Biography #Birth_Date #Events #05июля
Ю́рис Ха́ртманис (латыш. Juris Hartmanis; 5 июля 1928, Рига — 29 июля 2022) — учёный в области теории вычислительных систем, награждён в 1993 году премией Тьюринга за достижения в исследовании теории сложности вычислений.
Уильям Джон Макуорн Ранкин (Ренкин) (англ. William John Macquorn Rankine; 5 июля 1820, Эдинбург — 24 декабря 1872, Глазго) — шотландский инженер, физик и механик, один из создателей технической термодинамики. В 1849 году независимо от Клаузиуса получил общие уравнения термодинамики, выражающие соотношение между количеством теплоты и механической энергией. Исследовал термодинамические свойства газов и пара в 1850 году и составил таблицы водяных паров получивших широкое применение. В 1859 году построил полную теорию паровой машины; в частности, разработал идеальный термодинамический цикл парового двигателя, названного в его честь.
Ге́рард Хо́фт (Герард эт Хоофт, нид. Gerardus (Gerard) ’t Hooft; род. 5 июля 1946, Ден-Хелдер, Северная Голландия) — голландский физик-теоретик, профессор Утрехтского университета (Нидерланды), лауреат Нобелевской премии по физике за 1999 год (совместно с Мартинусом Велтманом). Разработанные Хофтом и Велтманом математические методы ренормализации янг-миллсовских полей, как безмассовых, так и получающих массу вследствие спонтанного нарушения симметрии, позволили рассчитать некоторые эффекты электрослабого взаимодействия, в частности, оценить массы промежуточных векторных бозонов W± и Z0, предсказанных теорией и вскоре после этого открытых экспериментально, причём полученные значения хорошо согласовывались с экспериментальными данными. Методом Велтмана и Хофта также была рассчитана масса топ-кварка, экспериментально обнаруженного в 1995 году в Национальной лаборатории им. Э. Ферми (США).
1996 — в Великобритании родилось первое клонированное млекопитающее — овца Долли
2016 — автоматическая межпланетная станция НАСА «Юнона», запущенная в 2011 году, вышла на полярную орбиту Юпитера.
#Biography #Birth_Date #Events #05июля
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3
История технологии сегодня — 6 июля
ℹ️ Кто родился в этот день
Бори́с Па́влович Константи́нов (23 июня (6 июля) 1910, Санкт-Петербург — 9 июля 1969, Ленинград) — советский учёный, физик-ядерщик, академик (с 1960; член-корреспондент с 1953), вице-президент Академии наук СССР (c 8 февраля 1966 по 9 июля 1969). Работы посвящены акустике, физической химии, физике изотопов, физике плазмы и проблеме управляемого термоядерного синтеза, астрофизике, голографии. В ФТИ им. А. Ф. Иоффе основал астрофизическую лабораторию и филиал ядерной физики (впоследствии ПИЯФ).
🌐 Знаковые события
1926 — в СССР открыта первая электрифицированная линия железной дороги (Баку-Сабунчи).
2003 — с помощью радиотелескопа РТ-70 под Евпаторией был передан Космический зов — кодированное послание к нескольким звёздам солнечного типа.
#Biography #Birth_Date #Events #06июля
Бори́с Па́влович Константи́нов (23 июня (6 июля) 1910, Санкт-Петербург — 9 июля 1969, Ленинград) — советский учёный, физик-ядерщик, академик (с 1960; член-корреспондент с 1953), вице-президент Академии наук СССР (c 8 февраля 1966 по 9 июля 1969). Работы посвящены акустике, физической химии, физике изотопов, физике плазмы и проблеме управляемого термоядерного синтеза, астрофизике, голографии. В ФТИ им. А. Ф. Иоффе основал астрофизическую лабораторию и филиал ядерной физики (впоследствии ПИЯФ).
1926 — в СССР открыта первая электрифицированная линия железной дороги (Баку-Сабунчи).
2003 — с помощью радиотелескопа РТ-70 под Евпаторией был передан Космический зов — кодированное послание к нескольким звёздам солнечного типа.
#Biography #Birth_Date #Events #06июля
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3
[Совет по Java #057]
Тема:
Проблема:
Решение: В пулах потоков избегайте использования
Объяснение:
В пулах потоков потоки создаются один раз и затем переиспользуются, поэтому наследование происходит только при инициализации пула. Если пул создан в главном потоке, то все задачи унаследуют контекст главного потока, а не контекст того потока, который отправил задачу. Если пул создается внутри задачи, то все потоки пула унаследуют контекст этой задачи, что также нежелательно. Таким образом,
#Java #советы
Тема:
ThreadLocal с InheritableThreadLocal опасен для пулов потоков.Проблема:
InheritableThreadLocal расширяет ThreadLocal и позволяет передавать значения из родительского потока в дочерний при создании нового потока. В средах с пулами потоков (например, ExecutorService, веб-контейнеры) потоки не создаются заново для каждой задачи, а переиспользуются. При использовании InheritableThreadLocal значения наследуются от потока, который создал пул (обычно главный поток приложения), а не от того, который поставил задачу. Это приводит к тому, что все задачи в пуле получают один и тот же контекст, либо, если пул был создан внутри другой задачи, дочерние задачи могут унаследовать контекст от случайной родительской задачи. В результате происходит утечка контекста безопасности, идентификатора пользователя, транзакционных данных и т.п., что приводит к непредсказуемому поведению и серьезным уязвимостям.Решение: В пулах потоков избегайте использования
InheritableThreadLocal. Если нужно передать контекст, используйте явные параметры в методах или передавайте контекст через ThreadLocal с ручной установкой и обязательной очисткой в блоке try-finally. Для безопасной передачи контекста между задачами в пулах применяйте ThreadLocal и устанавливайте его значение перед выполнением задачи, очищая после. В высоконагруженных системах рассмотрите использование ScopedValue (Java 21+), который предназначен для передачи значений без утечек. Никогда не полагайтесь на автоматическое наследование в пулах потоков.public class InheritableThreadLocalPitfall {
//Опасно: InheritableThreadLocal в пуле
private static final InheritableThreadLocal<String> USER_CONTEXT =
new InheritableThreadLocal<>();
public static void main(String[] args) throws InterruptedException {
ExecutorService executor = Executors.newFixedThreadPool(2);
// Главный поток устанавливает контекст
USER_CONTEXT.set("Admin");
// Задача, которая пытается получить унаследованное значение
executor.submit(() -> {
// Выведет "Admin", даже если ожидается другой контекст
System.out.println("Task 1 - inherited: " + USER_CONTEXT.get());
});
// Меняем контекст перед новой задачей в главном потоке
USER_CONTEXT.set("Guest");
executor.submit(() -> {
// Выведет "Guest" (текущее значение главного потока)
System.out.println("Task 2 - inherited: " + USER_CONTEXT.get());
});
// В реальности пул создан один раз, и значения берутся из главного
// потока в момент создания пула или подачи задачи? На самом деле
// наследование происходит при создании потока, а не при submit.
// В данном примере потоки уже созданы, поэтому унаследованных значений нет.
// Это показывает, что наследование происходит только при создании потока.
// Если создать новый пул внутри другой задачи, то контекст унаследуется
// от родительской задачи, что тоже опасно.
executor.shutdown();
}
}//Безопасный подход: явная передача контекста
public class SafeThreadLocal {
private static final ThreadLocal<String> CONTEXT = new ThreadLocal<>();
public static void executeWithContext(ExecutorService executor,
String user, Runnable task) {
executor.submit(() -> {
try {
CONTEXT.set(user);
task.run();
} finally {
CONTEXT.remove(); // обязательная очистка
}
});
}
public static void main(String[] args) {
ExecutorService executor = Executors.newFixedThreadPool(2);
executeWithContext(executor, "Admin", () -> {
System.out.println("Working as: " + CONTEXT.get());
});
executor.shutdown();
}
}
Объяснение:
InheritableThreadLocal работает только в момент создания нового потока — он копирует значения из родительского потока в новый поток. В пулах потоков потоки создаются один раз и затем переиспользуются, поэтому наследование происходит только при инициализации пула. Если пул создан в главном потоке, то все задачи унаследуют контекст главного потока, а не контекст того потока, который отправил задачу. Если пул создается внутри задачи, то все потоки пула унаследуют контекст этой задачи, что также нежелательно. Таким образом,
InheritableThreadLocal нарушает принцип изоляции задач в пуле. Правильный подход — явно устанавливать контекст для каждой задачи и обязательно очищать его после выполнения, чтобы избежать утечек между задачами в одном потоке. Начиная с Java 21, ScopedValue предоставляет безопасную альтернативу для передачи значений, которая автоматически очищается.#Java #советы
👍4
Что выведет код?
#Tasks
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class Task060726 {
private static final InheritableThreadLocal<String> threadLocal = new InheritableThreadLocal<>();
public static void main(String[] args) {
threadLocal.set("main");
ExecutorService executor = Executors.newFixedThreadPool(1);
for (int i = 0; i < 3; i++) {
final int taskId = i;
executor.submit(() -> {
if (threadLocal.get() == null) {
threadLocal.set("task" + taskId);
}
System.out.print(threadLocal.get() + " ");
});
}
executor.shutdown();
}
}
#Tasks
👍3