返回信息流public class IncomingReader implements Runnable {
public void run() {
String message;
try {
while ((message = reader.readLine()) != null) {
System.out.println("read " + message);
incoming.append(message + "\n");
} // close while
} catch(Exception ex) {ex.printStackTrace();}
} // close run
} // close inner class
Head First Java中的SimpleChatClient程序中的线程部分。这是一个聊天室的客户端,这段程序是新开的线程,实现的功能是当发送字符串到服务器端后,服务器会将字符串传回来,线程中的程序收到字符串并显示在TextArea中。
疑问是:线程中使用while循环,当一轮发送传回结束(message = reader.readLine()) != null为否即没有再收到服务器传回的字符串时,不是应该跳出循环线程结束吗,为什么线程并没有结束而是继续发送字符串还是能收到传回的?
客户端完整代码如下:
import java.io.*;
import java.net.*;
import java.util.*;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class SimpleChatClient {
JTextArea incoming;
JTextField outgoing;
BufferedReader reader;
PrintWriter writer;
Socket sock;
public static void main(String[] args) {
SimpleChatClient client = new SimpleChatClient();
client.go();
}
public void go() {
// build gui
JFrame frame = new JFrame("Ludicrously Simple Chat Client");
JPanel mainPanel = new JPanel();
incoming = new JTextArea(15,20); // was 15,50
incoming.setLineWrap(true);
incoming.setWrapStyleWord(true);
incoming.setEditable(false);
JScrollPane qScroller = new JScrollPane(incoming);
qScroller.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
qScroller.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
outgoing = new JTextField(20);
JButton sendButton = new JButton("Send");
sendButton.addActionListener(new SendButtonListener());
mainPanel.add(qScroller);
mainPanel.add(outgoing);
mainPanel.add(sendButton);
setUpNetworking();
Thread readerThread = new Thread(new IncomingReader());
readerThread.start();
frame.getContentPane().add(BorderLayout.CENTER, mainPanel);
frame.setSize(400,500);
frame.setVisible(true);
} // close go
private void setUpNetworking() {
try {
sock = new Socket("127.0.0.1", 5000);
InputStreamReader streamReader = new InputStreamReader(sock.getInputStream());
reader = new BufferedReader(streamReader);
writer = new PrintWriter(sock.getOutputStream());
System.out.println("networking established");
} catch(IOException ex) {
ex.printStackTrace();
}
} // close setUpNetworking
public class SendButtonListener implements ActionListener {
public void actionPerformed(ActionEvent ev) {
try {
writer.println(outgoing.getText());
writer.flush();
} catch(Exception ex) {
ex.printStackTrace();
}
outgoing.setText("");
outgoing.requestFocus();
}
} // close SendButtonListener inner class
public class IncomingReader implements Runnable {
public void run() {
String message;
try {
while ((message = reader.readLine()) != null) {
System.out.println("read " + message);
incoming.append(message + "\n");
} // close while
} catch(Exception ex) {ex.printStackTrace();}
} // close run
} // close inner class
}
这是一条镜像帖。来源:北邮人论坛 / java / #46696同步于 2015/12/28
该镜像源已超过 30 天没有更新,可能在源站已被删除。
Java机器人发帖
[问题]《Head First Java》中的一个关于线程的疑惑
shengyingpo
2015/12/28镜像同步15 回复
订阅后,新回复会通过你的通知中心匿名送达。
9 条回复
程序里没有让结束线程啊,所以这个线程还是在继续运行啊,不停地在判断 while ((message = reader.readLine()) != null)
【 在 shengyingpo 的大作中提到: 】
: public class IncomingReader implements Runnable {
: public void run() {
: String message;
: ...................
那就是服务器并没有断开连接,自然readLine也就没有返回null了。
另外,Swing很多组件都不是线程安全的,只有消息处理线程可以去修改UI。所以,不要用多个线程去同时操作图形界面。这里有详细叙述: https://docs.oracle.com/javase/tutorial/uiswing/concurrency/
java里的线程需要程序来终断吗?不是运行到最后自动结束?
【 在 xrjervis (万物生长) 的大作中提到: 】
: 程序里没有让结束线程啊,所以这个线程还是在继续运行啊,不停地在判断 while ((message = reader.readLine()) != null)
通过『我邮2.0』发布
原来是这样,多谢暖神!
【 在 nuanyangyang (暖羊羊) 的大作中提到: 】
: 那就是服务器并没有断开连接,自然readLine也就没有返回null了。
: 另外,Swing很多组件都不是线程安全的,只有消息处理线程可以去修改UI。所以,不要用多个线程去同时操作图形界面。这里有详细叙述: https://docs.oracle.com/javase/tutorial/uiswing/concurrency/
通过『我邮2.0』发布
不是吗?你看看程序里新建线程后有readThread.start(),但是并没有readThread.stop(),你启动了这个线程那它就不停地执行run()中的代码,当服务器没有数据传回时,那么readLine()就是null,然后又继续执行run(),然后又判断readLine(),只有当又有数据发送时readLine()才!=null,你没有结束线程它就一直在执行呀,这个程序的功能又不是只能收发一次数据
【 在 shengyingpo 的大作中提到: 】
: java里的线程需要程序来终断吗?不是运行到最后自动结束?
:
: 通过『我邮2.0』发布
在while外写一个println("end"),运行时并没有显示,也就是说其实连while都没出去过,更不用说是线程结束又重启了
【 在 xrjervis (万物生长) 的大作中提到: 】
: 不是吗?你看看程序里新建线程后有readThread.start(),但是并没有readThread.stop(),你启动了这个线程那它就不停地执行run()中的代码,当服务器没有数据传回时,那么readLine()就是null,然后又继续执行run(),然后又判断readLine(),只有当又有数据发送时readLine()才!=null,你没有结束线程它就一直在执行呀,这个程序的功能又不是只能收发一次数据
通过『我邮2.0』发布
挺基础的,讲的也比较有意思,很简单,适合做入门书
【 在 dongqing (dongqing) 的大作中提到: 】
: head first java 这本书 怎么样?
通过『我邮2.0』发布
手贱写了个聊天服务器+客户端的程序。多线程,但最后还是没有妥善处理退出的问题……于是开始对我的多线程编程能力感到怀疑了。
密集物体恐惧症患者慎看。
【 在 shengyingpo 的大作中提到: 】
: public class IncomingReader implements Runnable {
: public void run() {
: String message;
: ...................