if(din.available()>0) 
   din.readLine()

解决方案 »

  1.   

    可以用多线程啊,开一个新的线程,将所要做的操作放到新线程中,当旧线程执行到din.readLine();这句话便会处于阻塞状态,新的线程就会开始执行,这样就到达你的目的了。
      

  2.   

    to :企鹅
    你的din.available()是一致连的,应该是中返回true。
    to :义水寒:
    可是那这个新线程和老线程还要互相通讯,因为还得互相传数据呀,这就陷入一个悖论了。
      

  3.   

    to all:
    我现在的run()已经多线程了。
    整个系统是这样的:
    Applet请求Socket服务,与服务程序建立连接后,服务主线程spawn一个子线程去和该客户端连接。主线程同时listen新的请求。每个子线程与主线程间是靠管道通讯。每个子线程既要和客户端保持链路,又要和主线程通讯。也就是while(1)中作的事情了。
    while(1)
    {
         checkNew();//与主线程联络,看有没有新的信息发给它。用管道实现。
              din.readLine();//与客户端联络,看由否新的信息。
    }
    这样的话,din.readLine()会阻塞住,没法执行checkNew()。
      

  4.   

    再写另一个线程运行run,
    或者你自己改一下java 1.4的NIO让它在1.3下好用不过个人觉得你的设计是不是有些问题啊,看能不能改一下
      

  5.   

    我看对应每个客户端应该有两个线程,分别和主线程、客户端通信,还要提供两个回调方法,供这两个子线程调用。 void callback1();
    void callback2();

    和主线程通信的线程:

    while(true){
    checkNew();
    callback1();
    }

    和客户端通信的线程:

    while(true){
    din.readLine();
    callback2();
    }
      

  6.   

    可以用socketServer.setSoTimeout();吗
      

  7.   

    to : chongkai
    即使再多的线程,二者间的通讯不也得用管道通讯吗?
    to farandfaraway(遥远) :
    这样设完后,是这样写吗?
    socketServer.setSoTimeout(100); //100毫秒
    while(1)
    {
        checkNew();//与主线程联络,看有没有新的信息发给它。用管道实现。
        try{
            din.readLine();//与客户端联络,看由否新的信息。
        }
        catch (TimeoutException e)//捕捉超时
        {
            continue;
        }
        catch (Exception e)
        {
            //报错
        }
    }
    对吗?
    to eureka0891(迷茫中...):我想做一个类似聊天室的东西,但不是每次客户端请求,而是每个客户端对应一个子线程服务,服务子线程收到它的消息后传递给主线程,再由主线程广播给其他子线程,这样子线程的工作中既包含与客户端的联系,又必须发送/接收主线程的消息。有什么别的方法吗?
      

  8.   

    我不知道你说的管道是什么东东。如果你要做聊天室这样的东西,可以参考以下代码。一般把可能阻塞的读操作放在另外的线程里,如果要向Socket里写东西,随时都可以直接写。
    每个Client对象创建时起一个线程,不断读取客户端发来的东西,然后把读取的内容交给Server,由Server在每个Client上(因为Server保存了所有Client的列表)调用send 方法发送出去。//for the server
    class Server{
    ServerSocket s;
    List clients; //hold all clients

    void fun(){
    while(true){
    Socket socket = s.accept();
    Client c = new Client(this, socket);
    clients.add(c);
    }
    }

    void broadcast(String s){
    for each c in clients{
    c.send(s);
    }
    }
    }//one instance for each client
    class Client implements Runnable{
    Socket s;
    Server server;
    BufferedReader reader;
    PrintWriter writer;

    Client(Server server, Socket s){
    this.s = s;
    this.server = server;

    //create reader from socket
    //create writer from socket

    new Thread(this).start();
    }

    public void run(){
    while(true){
    String line = reader.readLine();
    server.broadcast();
    }

    }


    public void send(String line){
    writer.println(line);
    }
    }
      

  9.   

    to chongkai:
    管道是指的多线程间的通讯,你程序里的client相当于我的服务程序的子线程,而你的Server相当于我的服务程序的主线程,但问题是你的client程序还要接收真正的从客户端的连接。就是在你的所谓client程序run()中:
    while(true)
    {
        String line=reder.readLine();
        server.broadcast();
        readFromRealClient();//通常是阻塞的
    }
      

  10.   

    1。你的管道怎么实现的?2。不知道你所说的“真正的”客户端是什么意思,Client对象构造时传入的Socket对象是ServerSocket.accept()的返回值,正是和客户端的网络连接,你所说的阻塞发生在String line=reder.readLine();为什么后面还要加上 readFromRealClient();另外sorry,server.broadcast()忘了加参数了: public void run(){
    while(true){
    String line = reader.readLine();
    server.broadcast(line);
    }

    }
      

  11.   

    管道就是主线程与子线程的通讯,使这样的,真正的客户端指的是客户的Applet网页,他通过socket与服务程序建立连接,服务程序fork出子线程处理相应交易,而主线程则负责在所有子线程间传递消息。这样的话每个子线程的任务又要与主线程通讯,还必须执行客户端的请求。所以说要有readFromRealClient();其实他本身也是一个read操作.
      

  12.   

    你怎么就不明白呢?
    我觉得我给你的代码完全能实现你的功能了。
    Server类的broadcast方法就是用来把一个子线程收到的消息发送到所有客户端去的。你是不是把问题想得太复杂了?
    在不同线程间通信时,回调方法是最简洁、有效的选择。broadcast就是Server提供给Client的回调方法。Client线程在readLine上阻塞,阻塞的时候并不妨碍它的send方法被Server的broadcast调用。你所说的readFromRealClient是不必要的,readLine就是做这个的。
    给你画个图吧
          Server
    |
    |
    -------------
    |    |
    |    |
         Client1   Client2
    |    |
    |    |
    |    |
         Applet1   Applet2