我如何确保:
1。)localThread
和remoteThread
彼此独立运行?
2。)在localThread
和remoteThread
之间传递消息?
具体来说,来自localThread
的String对象需要“渗透”到Telnet
,我认为这是一个回调。但是,Telnet
到observe
本身并没有什么。这是对LocalIO
的匿名引用,我没有看到明确提供引用帮助。
我读到java.util.concurrent.Semaphore
直到我的头部爆炸,我所带走的是它似乎不适用。对于这两个线程,无论其他线程在做什么,它们都应该继续运行。但是,需要有一些机制来在线程之间传递对象引用...
public class Telnet {
public Telnet() throws InterruptedException {
startThreads();
}
public static void main(String[] args) throws InterruptedException {
new Telnet();
}
public void startThreads() throws InterruptedException {
Semaphore s = new Semaphore(1, true);
Thread localThread = new Thread(new LocalIO());
Thread remoteThread = new Thread(new RemoteIO());
localThread.start();
remoteThread.start();
}
}
线程本身如下。 LocalIO
:
public class LocalIO implements Runnable {
@Override
public void run() {
Scanner scanner;
String line;
while (true) {
scanner = new Scanner(System.in);
line = scanner.nextLine();
out.println("\n\nyou entered\t\"" + line + "\"\n");
}
}
}
RemoteIO
:
public class RemoteIO implements Runnable {
private static Logger log = Logger.getLogger(RemoteIO.class.getName());
final String host = "rainmaker.wunderground.com";
final int port = 3000;
@Override
public void run() {
log.fine(host + port);
int byteOfData;
try (Socket socket = new Socket(host, port);
InputStream inputStream = socket.getInputStream();
OutputStream ouputStream = socket.getOutputStream();
PrintWriter printWriter = new PrintWriter(socket.getOutputStream(), true);
final BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in))) {
while ((byteOfData = inputStream.read()) != -1) {
out.print((char) byteOfData);
}
} catch (Exception e) {
out.println(e);
}
}
}
请记住,RemoteIO
永远不会关闭其连接并无限期地运行。
答案 0 :(得分:2)
并发包对这类事情非常有帮助: http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/package-summary.html
例如,你可以给每个线程一个ConcurrentLinkedQueue,他们可以检查队列,看看是否有什么可以随时采取行动。同时,其他线程可以随时将新对象添加到队列中。
答案 1 :(得分:1)
您的代码可以采用的编程范例有一个本质区别:
同步模式:接收端运行一个无限循环,显式从并发队列中取出项目,在没有项目准备就阻止;
异步模式:接收端向项目交换机制提交回调。对于从生产者线程到达的每个项目都会调用此回调。
Observer 模式可能会松散地适用于后者,但不适用于前者。
另请注意,在后一种情况下,“项目交换机制”通常以同步模式实现。
答案 2 :(得分:1)
不确定你想要做什么,但如果你想在线程之间交换数据,你需要一个volatile变量来确保其他线程看到更改。 AtomicReferences是非阻塞的,并提供了一些可能对此有帮助的API。
答案 3 :(得分:0)
我发现的解决方案:
public class RemoteConnection extends Observable {
private static Logger log = Logger.getLogger(RemoteConnection.class.getName());
private final Socket socket;
private final BufferedInputStream in;
private final BufferedOutputStream out;
private final static String UTF8 = "UTF-8";
public RemoteConnection(String host, int port) throws UnknownHostException, IOException {
socket = new Socket(host, port);
in = new BufferedInputStream(socket.getInputStream());
out = new BufferedOutputStream(socket.getOutputStream());
}
public void write(Deque<String> commands) throws IOException {
String command;
while (!commands.isEmpty()) {
command = commands.pop();
out.write(command.concat("\r\n").getBytes(Charset.forName(UTF8)));
log.info(command);
}
out.flush();
}
void read() { //probably should use BufferedStream to better effect..?
Thread readRemote = new Thread() {
@Override
public void run() {
StringBuilder sb = new StringBuilder();
char ch;
int i;
while (true) {
try {
i = in.read();
ch = (char) i;
sb.append(ch);
System.out.print(ch);
if (i == 13) {
setChanged();
notifyObservers(sb.toString());
log.fine(sb.toString());
sb = new StringBuilder();
}
} catch (IOException ioe) {
log.fine(ioe.toString());
}
}
}
};
readRemote.start();
}
}
通过重新组织线程,这近似于一个穷人的telnet,具有i / o的异步线程。我认为从控制台阅读是阻止......某事......
我真的不知道为什么会这样,但其他方法却没有。我宁愿让主类启动和处理线程,并在线程之间传递引用,但是尽管使用了这里提供的各种解决方案,但这样做并不起作用。
LocalConnection有类似的线程方法。