Netty核心组件
Channel
CallBack
Future
Event & ChannelHandler
Channel
channel 抽象了一个关联到文件描述符的全双工(双向)连接,关键操作有:连接,断开,打开,关闭,读,写。
CallBack
这个无需多谈
Future
这是一个异步操作结果的占位符。每一个Netty的出站(例如服务端编程,出站就是输出到客户端的I/O)I/O操作都会返回一个ChannelFuture。
回调和Future是相互互补的机制,他们是Netty的关键机制。
java Future回顾
Runnable:封装一个可异步执行的任务,可以看成一个没有参数和返回值的异步方法。
Callable:与Runnable相似,但是有返回值。
Future:保存异步计算的结果
import java.util.Date;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.FutureTask;
public class Main {
public static void main(String[] args) {
// TODO Auto-generated method stub
System.out.println("fuck hello word");
// testRunnbale();
// testCallableAndFuture();
// testCallableAndFuture_1();
}
public static void testRunnbale() {
Runnable runnable = new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
for (int i = 0; i < 5; i++) {
System.out.println(new Date(System.currentTimeMillis()).toGMTString());
try {
Thread.sleep(1000);
} catch (Exception e) {
e.printStackTrace();
}
}
}
};
new Thread(runnable).start();
System.out.println("start finish");
}
public static void testCallableAndFuture_1() {
Callable<String> callbale = new Callable<String>() {
@Override
public String call() throws Exception {
for (int i = 0; i < 5; i++) {
System.out.println(new Date(System.currentTimeMillis()).toGMTString());
try {
Thread.sleep(1000);
} catch (Exception e) {
e.printStackTrace();
}
}
return new Date(System.currentTimeMillis()).toGMTString();
}
};
FutureTask<String> task = new FutureTask<String>(callbale);
new Thread(task).start();
System.out.println("start finish");
try {
System.out.println("task result-->" + task.get());
} catch (InterruptedException | ExecutionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static void testCallableAndFuture() {
Callable<String> callbale = new Callable<String>() {
@Override
public String call() throws Exception {
for (int i = 0; i < 5; i++) {
System.out.println(new Date(System.currentTimeMillis()).toGMTString());
try {
Thread.sleep(1000);
} catch (Exception e) {
e.printStackTrace();
}
}
return new Date(System.currentTimeMillis()).toGMTString();
}
};
ExecutorService pool = Executors.newFixedThreadPool(1);
Future<String> future = pool.submit(callbale);
System.out.println("start finish");
try {
System.out.println("future result-->" + future.get());
} catch (InterruptedException | ExecutionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
testRunnbale执行结果:
fuck hello word
start finish
10 Jan 2018 06:13:50 GMT
10 Jan 2018 06:13:51 GMT
10 Jan 2018 06:13:52 GMT
10 Jan 2018 06:13:53 GMT
10 Jan 2018 06:13:54 GMT
testCallableAndFuture执行结果:
fuck hello word
start finish
10 Jan 2018 06:14:48 GMT
10 Jan 2018 06:14:49 GMT
10 Jan 2018 06:14:50 GMT
10 Jan 2018 06:14:51 GMT
10 Jan 2018 06:14:52 GMT
future result-->10 Jan 2018 06:14:53 GMT
testCallableAndFuture_1执行结果:
fuck hello word
start finish
10 Jan 2018 06:15:41 GMT
10 Jan 2018 06:15:42 GMT
10 Jan 2018 06:15:43 GMT
10 Jan 2018 06:15:44 GMT
10 Jan 2018 06:15:45 GMT
task result-->10 Jan 2018 06:15:47 GMT
Event & ChannelHandler
Netty被设计成事件驱动模式。Event可能是
进站事件:连接被激活、连接失活、数据读取、用户事件、错误事件
出站事件:打开连接、关闭连接、将数据写到或者冲刷到套接字
Channel Handler是处理这些事件的类。Netty预定义了大量可用的ChannelHandler的实现。
EventLoop
Netty会为每个Channel分配一个EventLoop,EventLoop本身是一个线程驱动,这个线程里面将包含Channel所有的I/O事件。