Всем здравствуйте.
Посмотрел я на 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, стандартное для всех ОС.





