I use Async Http Client library for download content to my server. My code looks like this:
AsyncHttpClient client = Dsl.asyncHttpClient();
FileChannel channel = new FileOutputStream("path_to_download").getChannel();
client.prepareGet("file).execute(new AsyncCompletionHandler<FileChannel>() {
@Override
public State onBodyPartReceived(HttpResponseBodyPart bodyPart)
throws Exception {
channel.write(bodyPart.getBodyByteBuffer()); //blocking operation
return State.CONTINUE;
}
@Override
public FileChannel onCompleted(Response response)
throws Exception {
channel.close();
return channel;
}
});
The problem is that in the onBodyPartReceived method. Since it is called several times and I write the incoming bytes to the FileChannel, at this point the thread is blocked.
There is a solution with AsynchronousFileChannel, but I looked at the source code of the main implementation of SimpleAsynchronousFileChannelImpl and ther in fact, the same thing happens, bytes writes in separate thread from Java cached thread pool. So this solution is async, but is blocking, cause it use for each write new thread.
Is there a way to write bytes to a file without creating unnecessary threads and not blocking the current thread?
UPDATE
I'll try to explain what I mean. AsyncHttpClient has as many threads as there are processor cores available. Suppose this number is 8. When data arrives to the onBodyPartReceived method, this code is conditionally speaking executed in the async-thread-3 thread. When I try to write incoming data to FileChannel, this thread is blocked and can no longer receive data. Therefore, I looked that there is a solution with AsynchronousFileChannel. But it has only one implementation - SimpleAsynchronousFileChannelImpl, which simply delegates write operation to the thread in cachedThreadPool. And this thread of cachedThreadPool is blocked, even though I released an async-3-thread.
So if I want to download 1000 files from the network and save it to disk, i need only 8 threads to read the data over the network, but for disk write I need 1000 threads. that is clearly ineffective. (although my disc is certainly faster than getting data over the network)