|
这几天想对之前写的一问一答网络通信程序作一些改进,改成任意一方都能连发多条消息,不必再发送一条之后等待对方回答.这要借助线程来实现,我的方法是将写的过程,即发送消息的过程用一个独立的线程来实现,而当客户端输入"over"时就关闭客户端。我的线程是这样写的: import java.io.*;
public class WriteThread extends Thread{ ObjectOutputStream output; BufferedReader in=new BufferedReader(new InputStreamReader(System.in)); public WriteThread(ObjectOutputStream output,String name){ super(name); this.output=output; } public void run(){ System.out.println("Thread write started."); try{ String message; while(true){ System.out.println(getName()+"->>"); message=in.readLine(); output.writeObject(message); output.flush(); if(message.toUpperCase().equals("OVER")){ break; } } } catch(IOException e){ System.err.println(getName()+" occurs IOException."); System.err.println("用抛异常的方法关闭前一个线程-〉下策"); } finally{ try{ in.close(); System.out.println("BufferedReader closed."); } catch(IOException e){ System.err.println("IOException in close BufferedReader."); } }关闭后再创建会抛异常 } } 他在客户端运行良好,但在服务器端会出现很多问题。其他的暂不讨论,主要说一下线程何时死亡的问题。 因为服务器是不关闭的,当一个客户端的连接中断后,服务器中处理通信的代码循环一遍结束,开始下一次循环。在下一次的循环中会重新创建写线程,这时如果前一个写线程未死亡,就会出现两个线程并行执行(客户端连接端口号不同,因此虽然同名,但构造函数的参数output不同,因此不是同一个线程),前一个线程再接受输入的话,就会在发送时找不到output流,因为它的客户端已经关闭了!这时就会在服务器端抛出异常!! 现在的关键就是,前一个写线程在他所在的方法执行结束时会死亡吗? 我做过试验,答案是不会死亡!尽管线程是在方法内声明和创建的,按照普遍的作用域的观点,他的作用域就是这个方法,方法结束了,他的生命周期就结束了。可是这个作用域的理论并不适合线程!我得出的结论是:线程一旦创建了,就与启动它的方法无关了,而是作为一个独立的运行单位,它的死亡条件也与方法的结束无关,要么用内部条件判断让其死亡,要么是创造异常,再要么就是结束主程序。 现在这个写线程不适合在服务器使用,解决办法可能是针对服务器专门设置一个写线程,目前还没尝试,改好之后再发言吧。
|
一共有 0 条评论