Selector select方法阻塞register的解决方法
来源:互联网 发布:西安广电网络电视台 编辑:程序博客网 时间:2024/06/03 21:22
1. 监听端口, 当连接到来的时候创建socketChannel
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() {@Overridepublic 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() {@Overridepublic 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);}}}
0 0
- Selector select方法阻塞register的解决方法
- 单线程中fgets阻塞select/poll/epoll的解决方法
- Applet的register方法
- AnnotationConfigApplicationContext的register方法
- select()的阻塞机制
- linux select阻塞非阻塞的使用
- select阻塞与非阻塞的含义
- 《Java源码解析》之NIO的Selector机制(Part2:SelectableChannel.register(Selector sel, int ops))
- Linux驱动学习8(非阻塞IO的实现--select/poll方法)
- TCP Server处理多Client请求的方法—非阻塞accept与select
- linearLayout下设置selector不起作用的解决方法
- 学习使用register定义变量的方法
- 学习使用register定义变量的方法。
- Swift-Selector方法的扩展
- 谈select和阻塞socket的关系
- 非阻塞式socket的select()用法
- 预防阻塞的方法
- gvim 出现 cannot register application object 错误信息的解决方法
- XMPP使用者
- 设计模式读书笔记:Factory Method(工厂方法)
- 《JAVA程序设计》第二次——《猜猜看》游戏
- 唯有坚持方能成功
- MPI安装问题
- Selector select方法阻塞register的解决方法
- 使用FreeSWITCH SIP落地的配置总结
- 【 C语言】将一个数字按字符形式逐个输出,例如1234,输出为1 2 3 4
- 查找图片
- iOS tableview cell 中自定义lable
- Win8.1的Matlab7卸载问题
- Java大文本文件切割
- LeetCode172_FactorialTrailingZeroes java题解
- leetcode 43 : Multiply Strings