Selector select方法阻塞register的解决方法
2015-07-03 11:29
387 查看
1. 监听端口, 当连接到来的时候创建socketChannel
由于select方法与register 方法都需要获取相同的监视器,故上面的方法会一直阻塞在register方法上
解决如下:
betty way:
public class MultiServer { public static void main(String[] args) throws IOException { ServerSocketChannel ss = ServerSocketChannel.open().bind( new InetSocketAddress(8484)); final Selector selector = Selector.open(); wuTiRaw(selector); while (true) { SocketChannel channel = ss.accept(); channel.configureBlocking(false); channel.register(selector, SelectionKey.OP_READ); } } private static void wuTiRaw(final Selector selector) { Thread t = new Thread(new Runnable() { @Override public void run() { while (true) { try { selector.select(); Set<SelectionKey> keys = selector .selectedKeys(); Iterator<SelectionKey> it = keys.iterator(); while (it.hasNext()) { SelectionKey next = it.next(); if (next.isReadable()) { ByteBuffer bb = ByteBuffer.allocate(10); SocketChannel channel = (SocketChannel) next .channel(); channel.read(bb); System.out.println(bb.toString()); } it.remove(); } } catch (IOException e1) { e1.printStackTrace(); } } } }); t.start(); }
由于select方法与register 方法都需要获取相同的监视器,故上面的方法会一直阻塞在register方法上
解决如下:
public class MultiServer { public static void main(String[] args) throws IOException { ServerSocketChannel ss = ServerSocketChannel.open().bind( new InetSocketAddress(8484)); final Selector selector = Selector.open(); SelectorHelper sh = new SelectorHelper(selector); wuTi(sh); while (true) { SocketChannel channel = ss.accept(); channel.configureBlocking(false); sh.reg(channel, SelectionKey.OP_READ); } } private static void wuTi(final SelectorHelper selector) { Thread t = new Thread(new Runnable() { @Override public void run() { while (true) { try { selector.select(); Set<SelectionKey> keys = selector.getSelector() .selectedKeys(); Iterator<SelectionKey> it = keys.iterator(); while (it.hasNext()) { SelectionKey next = it.next(); if (next.isReadable()) { ByteBuffer bb = ByteBuffer.allocate(10); SocketChannel channel = (SocketChannel) next .channel(); channel.read(bb); System.out.println(bb.toString()); } it.remove(); } } catch (IOException e1) { e1.printStackTrace(); } } } }); t.start(); } public static class SelectorHelper { private volatile boolean mark = false; private final Selector selector; public SelectorHelper(Selector selector) { this.selector = selector; } public Selector getSelector() { return selector; } /** * 必须是同步的, 保证多个线程调用reg的时候不会出现问题 * @param channel * @param op * @return * @throws ClosedChannelException */ public synchronized SelectionKey reg(SelectableChannel channel, int op) throws ClosedChannelException { mark = true; selector.wakeup(); SelectionKey register = channel.register(selector, op); mark = false; return register; } public int select() throws IOException { for (;;) { if (mark == true) continue; int select = selector.select(); if (select >= 1) return select; } } } }
betty way:
public class MultiServer2 { public static void main(String[] args) throws IOException { ServerSocketChannel serverChannel = ServerSocketChannel.open() .bind(new InetSocketAddress(8484)); Selector selector = Selector.open(); serverChannel.configureBlocking(false); serverChannel.register(selector, SelectionKey.OP_ACCEPT); while(true) { if(selector.select() == 0 ) continue; Set<SelectionKey> selectedKeys = selector.selectedKeys(); Iterator<SelectionKey> it = selectedKeys.iterator(); while(it.hasNext()) { SelectionKey next = it.next(); it.remove(); handleReady(next, selector); } } } private static void handleReady(SelectionKey next, Selector selector) throws IOException { if(next.isAcceptable()) { ServerSocketChannel channel = (ServerSocketChannel)next.channel(); SocketChannel accept = channel.accept(); accept.configureBlocking(false); accept.register(selector, SelectionKey.OP_READ); } if(next.isReadable()) { ByteBuffer bb = ByteBuffer.allocate(10); SocketChannel channel =(SocketChannel) next.channel(); channel.read(bb); System.out.println(bb); } } }
相关文章推荐
- MPI安装问题
- iOS多线程GCD(转)
- POJ读书笔记2.1 —— 鸡兔笼带
- 【转】Android 最火框架XUtils之注解机制详解
- Android 建造者(Builder)模式
- XMPP使用者
- 设计模式大全
- 设计模式读书笔记:Factory Method(工厂方法)
- 思科测试命令show和debug
- 360°全景效果展示
- mysql中判断记录是否存在方法比较
- swift 之嵌套的理解 func chooseStepFunction(backwards: Bool) -> (Int) -> Int
- 2015华为软赛(七)——动作一
- History discussion from chromium-dev
- 用于 iOS/Mac 的流媒体播放引擎 DOUAudioStreamer
- Memcache和Redis区别
- 清除缓存
- 《java实习》日志 周五 添加了提示框
- SQL 索引
- EasySize.h