Всем здравствуйте.
Посмотрел я на API богомерзкой .NET – и там в классе System.IO.File
есть семейство методов Read...Async
, возвращающих task<T>
либо от массива байт (byte[]
), либо от строки (string
). Заводить фоновый поток исполнения (хоть managed, хоть native – неважно) не требуется. На оффтопике всё это работает через т. наз. Overlapped_I/O, и я предполагаю, что в рамках проектов .NET Core и Mono то же самое API правильно портировано на Linux и BSD.
А потом я посмотрел на реализацию java.nio.channels.AsynchronousFileChannel
(и наследников) в стандартной библиотеке Java – и там, наоборот, при создании канала ввода/вывода нужно либо предоставить свой фоновый пул потоков (внутри ExecutorService
), либо использовать пул по умолчанию.
И то, и другое означает, что, если к вашему сервису придёт миллион китайцев, то либо китайцы будут ждать, либо сервис ляжет с OOME, не справившись с созданием стотысячного потока.
И вот тут напрашивается вопрос – а почему? Почему в Java нельзя было сделать так же, как в .NET? Ведь есть:
- kernel-accelerated AIO,
O_DIRECT
иepoll
в Linux; - I/O Completion Ports в AIX и Solaris;
kqueue()
иkevent()
в BSD и Mac OS X;- наконец, POSIX AIO, стандартное для всех ОС.