比如我要向远端传1G的数据,需要10分钟,那线程是一直堵塞在那里还是异步执行当前线程继续走下一步?

解决方案 »

  1.   

    如果你用阻塞IO的话 就会阻塞(比如Socket) 如果你用非阻塞IO就不会阻塞(SocketChannel 开启非阻塞模式用ByteBuffer输出数据)另外 IO阻塞是阻塞的一种情况 正常操作系统也有IO阻塞 只是阻塞时间太短你感受不到而已
      

  2.   

    我是用接收到的Socket创建了一个返回OutputStream流,现在遇到一个很难重现的情况,之前对方客户端会发生错误说我这里强制关闭了一个连接(不是经常有但是会发生),我这里没有报错,看了半天会不会是因为我用OutputStream返回内容时再还没有完全写光就Close掉了连接,因为在write和flush之后紧跟的就是Close(包括关闭Socket和OutputStream)
      

  3.   

    感觉楼上2位都答非所问按照楼主的假设,你用OutputStream的write传1G的数据,需要10分钟,那么当前线程就会在这个地方停留10分钟,直到write返回。
      

  4.   


    你在OutputStream的write和flush后,马上Close的话,对方就90%都会从他那边的输入流中读不到东西,而是会从输入流中读到-1。
    按照楼主的描述,你写的应该是服务端,你在回复完数据后,不能关闭socket。而是要等待对方来关闭,或者到了你设定的一个超时时长。
      

  5.   

    流程是我先接收对方发给我的一个Socket包,然后处理完毕,使用这个Socket创建的OutputStream返回结果,然后我直接关闭这个Socket,我这里是不是应该不需要关闭Socket让对方去关闭?
      

  6.   

    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.InputStreamReader;
    import java.io.OutputStream;
    import java.io.PrintWriter;
    import java.net.InetAddress;
    import java.net.ServerSocket;
    import java.net.Socket;
    import java.util.concurrent.TimeUnit;
    import java.util.concurrent.atomic.AtomicBoolean;
    import java.util.concurrent.locks.Lock;
    import java.util.concurrent.locks.ReentrantLock;/**
     * 这个程序仅仅是为了让你明白服务端或者客户端关闭对双方造成的影响(其实没啥影响..)
     * 发生你的异常的原因主要是你尝试向一个服务/客户端已经关闭的输入流输出内容
     * 通过调整一些属性可以更改这个程序的运行流程 用Lock来保证程序的执行顺序(通过设置IS_CLOSE_SERVER来确定是先关闭服务端还是客户端 另外凡是先关闭那一方都是负责输出内容)
     * @author Lv9
     */
    public class StudySocket {
    static final int PORT = 14455;
    static final boolean IS_CLOSE_SERVER = true;// true为先关闭服务端 false为先关闭客户端
    static final Lock LOCK = new ReentrantLock(); static java.util.concurrent.atomic.AtomicBoolean isAccpet = new AtomicBoolean(); public static void main(String[] args) {
    new Thread(new Server()).start();
    new Thread(new Client()).start();
    } static void send(OutputStream o, String message) {
    PrintWriter out = new PrintWriter(o);
    out.print("Hello World");
    out.flush();
    out.close();
    System.err.println("OutputStream is closed");
    } static String receive(InputStream i) throws IOException {
    StringBuilder result = new StringBuilder();
    BufferedReader reader = new BufferedReader(new InputStreamReader(i)); String line = null;
    while ((line = reader.readLine()) != null) {
    result.append(line).append("\r\n");
    } reader.close();

    System.err.println("InputStream is closed");
    return result.toString();
    } static class Client implements Runnable {
    private Socket client; public Client() {
    } @Override
    public void run() {
    try {
    try {
    while (!isAccpet.get()) {
    TimeUnit.SECONDS.sleep(2);
    }
    if (!IS_CLOSE_SERVER) {
    LOCK.lock();
    }
    } catch (InterruptedException e) {
    throw new RuntimeException(e);
    } this.client = new Socket(InetAddress.getLocalHost(), PORT); if (!IS_CLOSE_SERVER) {
    send(client.getOutputStream(), "I'm client.");
    LOCK.unlock();
    } else {
    LOCK.lock();
    System.err.println(receive(client.getInputStream()));
    }
    } catch (IOException e) {
    throw new RuntimeException(e);
    }
    }
    } static class Server implements Runnable {
    private ServerSocket server; public Server() {
    try {
    this.server = new ServerSocket(PORT);
    } catch (IOException e) {
    throw new RuntimeException(e);
    }
    } @Override
    public void run() {
    Socket socket = null;
    try {
    if (IS_CLOSE_SERVER) {
    LOCK.lock();
    }
    isAccpet.set(true);
    socket = server.accept(); if (IS_CLOSE_SERVER) {
    send(socket.getOutputStream(), "I'm server."); LOCK.unlock();
    } else {
    LOCK.lock();
    System.err.println(receive(socket.getInputStream()));
    }
    } catch (IOException e) {
    e.printStackTrace();
    }
    }
    }
    }