notify controller of changes to a ConcurrentLinkedQueue across threads
Along the lines of the Apache WeatherTelnet example, I have the following
classes:
NetBeansProjects/Telnet/src/telnet/
„¥„Ÿ„Ÿ Controller.java
„¥„Ÿ„Ÿ Printer.java
„¥„Ÿ„Ÿ PropertiesReader.java
„¥„Ÿ„Ÿ StreamReader.java
„¥„Ÿ„Ÿ StringReader.java
„¥„Ÿ„Ÿ TelnetConnection.java
„¤„Ÿ„Ÿ Telnet.java
Controller is supposed to manage communication between StreamReader,
StringReader and Printer. This is, I think, the "problem" class:
public class Controller {
private final static Logger LOG =
Logger.getLogger(Controller.class.getName());
private StringReader p = new StringReader();
public Controller() {
}
public void readParse(final InputStream inputStream) throws
SocketException, IOException {
final ConcurrentLinkedQueue<Character> clq = new
ConcurrentLinkedQueue();
final StringBuilder sb = new StringBuilder();
Printer print = new Printer();
print.print(inputStream, clq);
StreamReader sp = new StreamReader();
sp.read(clq);
}
}
because it's not receiving any messages or notifications from the objects
it should be, literally, controlling.
Printer simply prints the InputStream to the console and, most
importantly, populates the ConcurrentlyLinkedQueue. (An array queue might
have advantages, but that's immaterial to the question here.) Printer:
public class Printer {
private final static Logger LOG =
Logger.getLogger(Printer.class.getName());
public Printer() {
}
public void print(final InputStream inputStream, final
ConcurrentLinkedQueue<Character> clq) {
//final ConcurrentLinkedQueue<Character> clq = new
ConcurrentLinkedQueue();
Thread print = new Thread() {
@Override
public void run() {
out.println("print..");
try {
char ch = (char) inputStream.read();
while (255 > ch && ch >= 0) {
clq.add(ch);
out.print(ch);
ch = (char) inputStream.read();
}
} catch (IOException ex) {
out.println("cannot read inputStream:\t" + ex);
}
}
};
print.start();
}
}
StreamReader will remove the data from the ConcurrentLinkedQueue in a
seperate thread, for StringReader:
public class StreamReader {
private final static Logger LOG =
Logger.getLogger(StreamReader.class.getName());
private static final long SLEEP_MILLS = 1000; // not the best way to wait
for more input
private StringReader t = new StringReader();
public StreamReader() {
}
public void read(final ConcurrentLinkedQueue<Character> clq) throws
SocketException, IOException {
final StringBuilder sb = new StringBuilder();
Thread makeString = new Thread() {
@Override
public void run() {
out.println("makeString..");
do {
try {
do {
char ch = clq.remove();
sb.append(ch);
} while (true);
} catch (java.util.NoSuchElementException |
ClassCastException e) {
out.println("cannot remove\t\t" + e);
try {
Thread.sleep(SLEEP_MILLS); //not optimal
} catch (InterruptedException interruptedException) {
out.println("cannot sleep1\t\t" +
interruptedException);
}
} finally {
out.println("finally -- waiting for more data.." +
sb);
String cmd = t.parse(sb.toString());
sb.delete(0, sb.length());
out.println("COMMAND IS\t\t\t"+ cmd);
try {
Thread.sleep(SLEEP_MILLS);
} catch (InterruptedException interruptedException) {
out.println("cannot sleep1\t\t" +
interruptedException);
}
}
} while (true);
}
};
makeString.start();
}
}
StringReader, very basic:
class StringReader {
public String parse(String s) {
String cmd = "not a real command";
out.println("\n\n\nstarting PARSING ..\n\n\n" + s + "\n\n\n");
if (s.contains("Press Return to continue:")) {
cmd = "send newline";
}
return cmd;
}
}
Focusing on the Controller, how can I modify the this class so that, when
notified by StreamReader it sends a message to StringReader and receives
back a String command from StringReader?
I believe this is a poor-mans Netty, towards a MUD client. The difficulty
has so far been in concurrently printing and reading the InputStream over
a live telnet connection.
(Each of these threads, and any additional threads, should never block
each other. Perhaps not the ideal design, but easier for me to deal with.)
No comments:
Post a Comment