java - SelectionKey iterator.remove() throws UnsupportedOperationException and infinite loop -
i have method opens connection, queries site, gets number of pages , uses nio concurrently retrieve of pages. first query done using urlconnection
, works fine. running in 2 issues when try use nio selectors , channels:
1) if don't remove key iterator, in runs in infinite loop printing size()
, sending queries. if try remove key, unsupportedoperationsexception. bah!
2) need deregister channel op_write after i've written socket? if so, can call channel.register(selector, selectionkey.op_read)
remove interest in writing?
public void test() throws ioexception { // create selector selector selector = selector.open(); system.out.println("opened"); // number of pages url itemurl = new url(item_url); urlconnection conn = itemurl.openconnection(); conn.setdooutput(true); outputstreamwriter out = new outputstreamwriter(conn.getoutputstream()); // out.write(getheaderstring(itemurl)); out.write(new query("", "internal hard drives", false, false, true, false, -1, 7603, 1, 14, -1, "", "price", 1).tostring()); out.close(); jsonreader in = new jsonreader(new inputstreamreader(conn.getinputstream())); jsonparser parser = new jsonparser(); jsonobject tempobj = (jsonobject) parser.parse(in); pages.setnumofpages(getnumberofiterations(tempobj.get("paginationinfo"))); system.out.println("pages: " + pages.getnumofpages()); // each page, create channel, attach selector interest in read // typically <= pages.getnumberofpages troubleshoot, i'm limiting once. (int = 1; <= 1; i++) { socketchannel channel = socketchannel.open(); channel.configureblocking(false); channel.connect(new inetsocketaddress(itemurl.gethost(), 80)); channel.register(selector, selectionkey.op_write | selectionkey.op_read); } selector.select(); set<selectionkey> sk = selector.keys(); while (!sk.isempty()) { system.out.println(sk.size()); iterator<selectionkey> iterator = sk.iterator(); while (iterator.hasnext()) { selectionkey key = iterator.next(); iterator.remove(); if (key.isreadable()) { socketchannel channel = (socketchannel) key.channel(); bytebuffer buf = bytebuffer.allocate(8192); channel.read(buf); buf.flip(); product p = parse(buf, product.class); if (p != null) { finalitems.add(p); system.out.println("item added!"); key.cancel(); } } else if (key.iswritable()) { socketchannel channel = (socketchannel) key.channel(); system.out.println(itemurl); system.out.println(new query("", "internal hard drives", false, false, true, false, -1, 7603, 1, 14, -1, "", "price", 1).tostring()); channel.write(bytebuffer.wrap(new query("", "internal hard drives", false, false, true, false, -1, 7603, 1, 14, -1, "", "price", 1).tostring() .getbytes())); } } selector.select(); sk = selector.keys(); } }
from http://docs.oracle.com/javase/6/docs/api/java/nio/channels/selector.html#keys()
"the key set not directly modifiable. key removed after has been cancelled , channel has been deregistered. attempt modify key set cause unsupportedoperationexception thrown."
you want using selector.selectedkeys();
"keys may removed from, not directly added to, selected-key set. attempt add object key set cause unsupportedoperationexception thrown."
selector.select(); set<selectionkey> sk = selector.selectedkeys();
and can use iterator.remove()
a example posted here http://tutorials.jenkov.com/java-nio/selectors.html @ bottom of page
Comments
Post a Comment