假设有意服务器和多个客户端进行通讯,服务器采用多线程来侦听客户端发来的数据,由于处于阻塞状态,那么如何终止服务器和客户端的通讯线程呢。资料上都说不建议使用stop,请高手指教!!

解决方案 »

  1.   

    以前写的一段练习。
    其中取消阻塞的方法并不可取,但在线程控制方面基本上还算正规import java.io.*;
    import java.net.*;
    import java.util.*;public class TestBlocking {
        static class Receiver extends Thread {
            private final int WAITING_TIME = 800;
            private final int COUNT_ONCE = 3;
            private Boolean terminate = false;        Socket socket;
            InetSocketAddress addr;        Receiver(Sender serv) {
                socket = new Socket();            
                addr = 
                    new InetSocketAddress(serv.getPort());
            }
            class Monitor implements Runnable {
                Thread me;
                Boolean stop = false;            public synchronized void wakeup() {
                    this.notify();
                    //System.out.printf("momi: wakeup, %b\n", terminate);
                }            public void start() {
                    me = new Thread(this);
                    //me.setPriority(Thread.MAX_PRIORITY);
                    me.start();
                }
                public synchronized void stop() {                
                    stop = true;                    
                    this.notify();                
                }
                
                public void run() {                
                    while (true) {
                        try {
                            synchronized (this){
                                wait(WAITING_TIME * 2);
                            }
                            if (stop) {                                
                                break;
                            }                            
                            
                            synchronized (this){
                                wait(WAITING_TIME);    
                            }
                            if (stop) {                                
                                break;
                            }
                            
                            synchronized(terminate) {
                                if (terminate) {
                                    try {
                                        socket.close();
                                        //break;
                                    } catch (IOException ioe) {
                                        ioe.printStackTrace();
    //                                } finally {
    //                                    socket = null;
    //                                    break;
                                    }
                                }
                            }
                        } catch (Exception e) {
                            e.printStackTrace();
                            continue;
                        }
                    }
                }
            }
                    
            public void run() {
                int times = 0;
                Monitor monitor = new Monitor();
                while (true) {
                    try {
                        socket.connect(addr, 40);
                    } catch (SocketTimeoutException ste) {
                        if (times++ < 10) {
                            System.out.println("recv: where are you?");
                        }
                        continue;
                    } catch (IOException ioe) {
                        break;
                    }
                }            terminate = false;
                monitor.start();
                            
                try {
                    InputStream in = socket.getInputStream();
                    //char[] buf = new char[50];
                    //int off = 0, len = COUNT_ONCE;                System.out.println("recv: Hello");
                    
                    while (true) {                                        
                        int c;
                        
                        System.out.print("recv heard: \n\t");
                        while (socket != null) {
                            synchronized(terminate) {
                                terminate = true;
                            }
                            monitor.wakeup();                        c = in.read();
                            if (c == -1) {
                                break;
                            }
                            System.out.print((char)c);
                            synchronized(terminate) {
                                terminate = false;
                                monitor.wakeup();
                            }
                        }                    break;
                    }            } catch (SocketException se) {
                    System.out.println(
                        "\nrecv: I can't bear to wart for so long time, bye!");
                    monitor.stop();
                } catch (Exception e) {    
                    e.printStackTrace();
                }
            }
        }    static class Sender extends Thread {
            private final int WAITING_TIME = 400;
            private final int COUNT_ONCE = 5;        private final String toSay = 
                "Hello, I love you, and you?";        private ServerSocket serv = null;        Sender() throws IOException{
                serv = new ServerSocket(0);
                serv.setSoTimeout(50);
            }
            public InputStream getStream(){
                return null;
            }
            public int getPort() {
                return serv.getLocalPort();
            }        public void run() {
                int times=0;
                System.out.println("serv want to say: \n\t" + toSay);
                while (true) {
                    try {
                        Socket socket = serv.accept();                    PrintWriter out = 
                            new PrintWriter(
                                new OutputStreamWriter(
                                    socket.getOutputStream()));                    InputStream in = 
                            socket.getInputStream();
                        
                        for (int i=0; i<toSay.length(); i+=COUNT_ONCE) {
                            int writeCount = toSay.length() - i;
                            writeCount = writeCount<=COUNT_ONCE ? 
                                writeCount : COUNT_ONCE;                        String s = toSay.substring(i, i + writeCount);                        
                            out.write(s);
                            out.flush();
                            
                            if (i<10) {
                                sleep(WAITING_TIME);
                            } else {
                                sleep(WAITING_TIME + 100);
                            }                        
                        }                    //out.close();                } catch (SocketTimeoutException ste) {
                        //ste.printStackTrace();
                        if (times++<3) {
                            System.out.println("serv: are you here?");
                        } else {                        
                            System.out.println("serv: oh, shit!");
                            System.out.println("\nUnagain: haha!");
                            break;
                        }
                    } catch (IOException ioe) {
                        ioe.printStackTrace();
                        break;
                    } catch (InterruptedException ire) {
                        ire.printStackTrace();
                        break;
                    }                
                }            if (serv != null && !serv.isClosed()) {
                    try {
                        serv.close();
                    } catch (IOException e) {
                    } finally {
                        serv = null;
                    }
                }
            }
        }    public static void main(String[] args) {
            try {
                Sender sender = new Sender();
                sender.start();
                (new Receiver(sender)).start();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
      

  2.   

    Interrupt方法用于调用wait或者sleep导致线程阻塞的情况下,对于等待IO造成的线程阻塞适用吗?
      

  3.   

    对,感觉应该用Interrupt(),然后抛InterruptedException
      

  4.   

    加一句,catch到InterruptedException后可以用return退出线程
      

  5.   

    public vid run()
    {
    try
    {
        while(!interrupted())
        {
           //do more work
        }
    }
    catch(InterruptedException e)
    {
        //
    }
    //线程终止
    }当我需要终止该线程的时候,我在另外的线程中调用该线程的interrupt()方法即可。
    这样做是否正确,请大家指正
      

  6.   

    对,不过你的线程终止应该写在catch里的,就是
    catch(InterruptedException e)
    {
        //线程终止
    }
    如果这个线程是t1,在另外一个线程就是t1.interrupt();
      

  7.   

    用NIO写哪?Socket的连接和waiting的等待计时也可以主动的终端链接吧!好像象直接杀线程的方式不会写