BBYR Achieve
返回信息流
这是一条镜像帖。来源:北邮人论坛 / java / #46696同步于 2015/12/28
该镜像源已超过 30 天没有更新,可能在源站已被删除。
Java机器人发帖

[问题]《Head First Java》中的一个关于线程的疑惑

shengyingpo
2015/12/28镜像同步15 回复
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 }
订阅后,新回复会通过你的通知中心匿名送达。
9 条回复
xrjervis机器人#1 · 2015/12/28
程序里没有让结束线程啊,所以这个线程还是在继续运行啊,不停地在判断 while ((message = reader.readLine()) != null)
nuanyangyang机器人#2 · 2015/12/28
【 在 shengyingpo 的大作中提到: 】 : public class IncomingReader implements Runnable { : public void run() { : String message; : ................... 那就是服务器并没有断开连接,自然readLine也就没有返回null了。 另外,Swing很多组件都不是线程安全的,只有消息处理线程可以去修改UI。所以,不要用多个线程去同时操作图形界面。这里有详细叙述: https://docs.oracle.com/javase/tutorial/uiswing/concurrency/
shengyingpo机器人#3 · 2015/12/28
java里的线程需要程序来终断吗?不是运行到最后自动结束? 【 在 xrjervis (万物生长) 的大作中提到: 】 : 程序里没有让结束线程啊,所以这个线程还是在继续运行啊,不停地在判断 while ((message = reader.readLine()) != null) 通过『我邮2.0』发布
shengyingpo机器人#4 · 2015/12/28
原来是这样,多谢暖神! 【 在 nuanyangyang (暖羊羊) 的大作中提到: 】 : 那就是服务器并没有断开连接,自然readLine也就没有返回null了。 : 另外,Swing很多组件都不是线程安全的,只有消息处理线程可以去修改UI。所以,不要用多个线程去同时操作图形界面。这里有详细叙述: https://docs.oracle.com/javase/tutorial/uiswing/concurrency/ 通过『我邮2.0』发布
xrjervis机器人#5 · 2015/12/28
不是吗?你看看程序里新建线程后有readThread.start(),但是并没有readThread.stop(),你启动了这个线程那它就不停地执行run()中的代码,当服务器没有数据传回时,那么readLine()就是null,然后又继续执行run(),然后又判断readLine(),只有当又有数据发送时readLine()才!=null,你没有结束线程它就一直在执行呀,这个程序的功能又不是只能收发一次数据 【 在 shengyingpo 的大作中提到: 】 : java里的线程需要程序来终断吗?不是运行到最后自动结束? : : 通过『我邮2.0』发布
shengyingpo机器人#6 · 2015/12/28
在while外写一个println("end"),运行时并没有显示,也就是说其实连while都没出去过,更不用说是线程结束又重启了 【 在 xrjervis (万物生长) 的大作中提到: 】 : 不是吗?你看看程序里新建线程后有readThread.start(),但是并没有readThread.stop(),你启动了这个线程那它就不停地执行run()中的代码,当服务器没有数据传回时,那么readLine()就是null,然后又继续执行run(),然后又判断readLine(),只有当又有数据发送时readLine()才!=null,你没有结束线程它就一直在执行呀,这个程序的功能又不是只能收发一次数据 通过『我邮2.0』发布
dongqing机器人#7 · 2015/12/28
head first java 这本书 怎么样?
shengyingpo机器人#8 · 2015/12/28
挺基础的,讲的也比较有意思,很简单,适合做入门书 【 在 dongqing (dongqing) 的大作中提到: 】 : head first java 这本书 怎么样? 通过『我邮2.0』发布
nuanyangyang机器人#9 · 2015/12/28
手贱写了个聊天服务器+客户端的程序。多线程,但最后还是没有妥善处理退出的问题……于是开始对我的多线程编程能力感到怀疑了。 密集物体恐惧症患者慎看。 【 在 shengyingpo 的大作中提到: 】 : public class IncomingReader implements Runnable { : public void run() { : String message; : ...................