现在的位置: 首页 > 综合 > 正文

vaniglia 源码学习 (六)

2012年07月29日 ⁄ 综合 ⁄ 共 1948字 ⁄ 字号 评论关闭

学习vaniglia源码中的socket部分,主要针对其server侧的代码实现做个记录。其代码有两部分值得学习,一块是实现了一个经典的线程池,另外一个是利用代理接口扩展业务的具体socket消息处理。

socket的server主要由三个部分组成:

  • ServerDelegate接口,提供readRequest、writeResult接口。由用户扩展并注册到SocketReceiver中;
  • SocketReceiver类,socket server的工作线程;
  • SocketServer类,初始化一个SocketReceiver的线程池,当accept返回时,唤醒空闲的SocketReceiver执行。

SocketServer核心代码主要是两个部分:

一是初始化线程池:

        SocketReceiver[] receivers = new SocketReceiver[numOfThreads];
        for (int i = 0; i < numOfThreads; i++) {
            ServerDelegate delegate = null;
            try {
                delegate = (ServerDelegate)serverDelegateClass.newInstance();
            } catch (InstantiationException e) {
                //略
            }
            SocketReceiver receiver = SocketReceiver.createSocketReceiver(delegate);//该函数中SocketReceiver线程被start
            receiversPool.addElement(receiver);//receiversPool是一个vector变量;
            receivers[i] = receiver;
        }

二是在accept返回时选择ready的线程执行,如下:

             SocketReceiver receiver = (SocketReceiver)receiversPool.get(receiverIndex);//receiverIndex是外侧循环的变量
                    receiverIndex = (receiverIndex + 1) % receiversPoolSize;//通过index遍历vector
                    if (receiver.isReady()) {
                        handling = true;
                        if (clientSocketSoTimeout > 0) {
                            logger.debug("Setting client socket SoTimeout to "+clientSocketSoTimeout+"ms");
                            try {
                                clientSocket.setSoTimeout(clientSocketSoTimeout);
                            } catch (SocketException e) {
                                logger.error("Exception while setting SoTimeout for client socket", e);
                            }
                        }
                        clientSocket.setTcpNoDelay(true);
                        receiver.handle(clientSocket);//一个工作线程被唤醒
                    }

SocketReceiver的核心代码是典型的工作线程,我将它简化成一个框架版本,如下:

public class Receive implements Runnable {
    private boolean ready;  
    Receive(){
        ready = true;
    }
    
    static Receive start(){
        Receive rev = new Receive();
        Thread t = new Thread(rev);
        t.start();
        return rev;
    }
    
    @Override
    public void run() {
        while(true){
            synchronized(this){
                while(true == ready){//当handler没有调用时该线程wait中。
                    try {
                        wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
            System.out.println("Receive run, service handler");//这部分的代码在在socket里就是处理input和output,实现时调用业务的代理接口。 
            ready = true;
            synchronized(this) {
                notify();
            }
        }
    }
    
    public synchronized void handler(){//有业务出发时,handler被调用
        while(ready == false){
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        ready = false;
        notify();
    }
}

 

抱歉!评论已关闭.