異步IO模型原理圖:
Java1.7中在NIO包中增加了Asynchronous I/O操作。
異步I/O類使用教程中講解得很好。
如何使用Asychronous I/O類
- JUC包中Fature
- Fature#isDone polling模式。輪訓檢查
- Fature#get wait模式。等待I/O操作完畢,也就是阻塞
- NIO包中CompletionHandler
- completed I/O執行完畢時的回調
- failed I/O執行失敗時的回調。好像ajax一樣,有成功與失敗的回調方法。
顯然,如果要實現異步I/O模型(非阻塞模式),需要使用回調的方法,也就是選擇CompletionHandler。
以下代碼片段摘自網絡java2s.com
import static java.nio.file.StandardOpenOption.CREATE;
import static java.nio.file.StandardOpenOption.WRITE;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.AsynchronousFileChannel;
import java.nio.channels.CompletionHandler;
import java.nio.charset.Charset;
import java.nio.file.Path;
import java.nio.file.Paths;
public class Main {
public static void main(String[] args) throws Exception {
Path path = Paths.get("test.txt");
AsynchronousFileChannel afc = AsynchronousFileChannel.open(path, WRITE,
CREATE);
WriteHandler handler = new WriteHandler();
ByteBuffer dataBuffer = getDataBuffer();
Attachment attach = new Attachment();
attach.asyncChannel = afc;
attach.buffer = dataBuffer;
attach.path = path;
afc.write(dataBuffer, 0, attach, handler);
System.out.println("Sleeping for 5 seconds...");
Thread.sleep(5000);
}
public static ByteBuffer getDataBuffer() {
String lineSeparator = System.getProperty("line.separator");
StringBuilder sb = new StringBuilder();
sb.append("test");
sb.append(lineSeparator);
sb.append("test");
sb.append(lineSeparator);
String str = sb.toString();
Charset cs = Charset.forName("UTF-8");
ByteBuffer bb = ByteBuffer.wrap(str.getBytes(cs));
return bb;
}
}
class Attachment {
public Path path;
public ByteBuffer buffer;
public AsynchronousFileChannel asyncChannel;
}
class WriteHandler implements CompletionHandler<Integer, Attachment> {
@Override
public void completed(Integer result, Attachment attach) {
System.out.format("%s bytes written to %s%n", result,
attach.path.toAbsolutePath());
try {
attach.asyncChannel.close();
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void failed(Throwable e, Attachment attach) {
try {
attach.asyncChannel.close();
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
import static java.nio.file.StandardOpenOption.READ;
/* w ww .j a v a 2 s. c o m*/
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.AsynchronousFileChannel;
import java.nio.channels.CompletionHandler;
import java.nio.charset.Charset;
import java.nio.file.Path;
import java.nio.file.Paths;
public class Main {
public static void main(String[] args) throws Exception{
Path path = Paths.get("test.txt");
AsynchronousFileChannel afc = AsynchronousFileChannel.open(path, READ);
ReadHandler handler = new ReadHandler();
int fileSize = (int) afc.size();
ByteBuffer dataBuffer = ByteBuffer.allocate(fileSize);
Attachment attach = new Attachment();
attach.asyncChannel = afc;
attach.buffer = dataBuffer;
attach.path = path;
afc.read(dataBuffer, 0, attach, handler);
System.out.println("Sleeping for 5 seconds...");
Thread.sleep(5000);
}
}
class Attachment {
public Path path;
public ByteBuffer buffer;
public AsynchronousFileChannel asyncChannel;
}
class ReadHandler implements CompletionHandler<Integer, Attachment> {
@Override
public void completed(Integer result, Attachment attach) {
System.out.format("%s bytes read from %s%n", result, attach.path);
System.out.format("Read data is:%n");
byte[] byteData = attach.buffer.array();
Charset cs = Charset.forName("UTF-8");
String data = new String(byteData, cs);
System.out.println(data);
try {
// Close the channel
attach.asyncChannel.close();
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void failed(Throwable e, Attachment attach) {
System.out.format("Read operation on %s file failed."
+ "The error is: %s%n", attach.path, e.getMessage());
try {
// Close the channel
attach.asyncChannel.close();
} catch (IOException e1) {
e1.printStackTrace();
}
}
}