V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
Event
V2EX  ›  问与答

Java 跑 tcp 的时候遇到一个很诡异的问题,不加一句 sout 不能成功给服务器发消息

  •  
  •   Event · 2018-11-13 21:05:36 +08:00 · 997 次点击
    这是一个创建于 1991 天前的主题,其中的信息可能已经有所发展或是发生改变。

    客户端有一个消息队列 发消息都是 msg.add(byte[]) 然后每次发送前输出 msg.size() 发送完就 remove 但是每次 msg.size 都在变大

    用调试看,也确实跑到了 remove 的位置

    然后我就发现了很诡异的情况 1.调试状态下服务端能收到消息,客户端的 size 也有在减小,消息有发出去 2.正常状态运行,似乎客户端的消息 write 不到 OutputStream 3.在每次发送消息前加一句 sout,消息就可以正常发出去和被收到,但是用 Thread.sleep 不行

    注:收消息发消息我都是专门建了一个 Thread 跑的。 猜测是不是出现了线程安全问题呢? 头疼 怎么调试都调试不出来

    贴出发送消息线程的代码:

    package com.lmyun.socket.thread;
    
    import com.lmyun.socket.SocketUtils;
    
    import java.io.IOException;
    import java.io.OutputStream;
    import java.net.Socket;
    import java.util.LinkedList;
    import java.util.List;
    
    public class SocketSendThread extends Thread {
        private Socket socket;
        private List<byte[]> msg;
    
        public SocketSendThread(Socket socket) throws IOException {
            this.socket = socket;
            this.msg = new LinkedList<>();
        }
    
        @Override
        public void run() {
            while (true) {
                //System.out.println(this.msg.size());
                if (msg.size() == 0) {
                    continue;
                }
                try {
                    this.sendMsg(msg.get(0));
                } catch (IOException e) {
                    e.printStackTrace();
                }
                msg.remove(0);
            }
        }
    
        public void addMsg(byte[] msg) {
            this.msg.add(msg);
            System.out.println(this.msg.size());
        }
    
        public void sendMsg(byte[] b) throws IOException {
            OutputStream os = this.socket.getOutputStream();
            os.write(SocketUtils.IntToByte(b.length));
            os.write(b);
            os.flush();
        }
    }
    

    太诡异!!!!!!!

    5 条回复    2018-11-13 21:21:48 +08:00
    mind3x
        1
    mind3x  
       2018-11-13 21:11:54 +08:00
    施主你可知道 LinkedList 不是线程安全的?
    好歹也用个 ArrayBlockingQueue 或者 LinkedBlockingQueue 吧
    Event
        2
    Event  
    OP
       2018-11-13 21:15:22 +08:00
    @mind3x ok 我去了解下。。
    Event
        3
    Event  
    OP
       2018-11-13 21:16:32 +08:00
    @mind3x 但是发送这个问题应该和这个没关系吧。。
    misaka19000
        4
    misaka19000  
       2018-11-13 21:21:42 +08:00
    remove 方法不改变 size 吧好像
    Event
        5
    Event  
    OP
       2018-11-13 21:21:48 +08:00
    @mind3x 谢谢。修改为 queue 的确解决了问题


    可是就算 linkedlist 是线程不安全 可为何取出数据后无法发送呢
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   2227 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 00:23 · PVG 08:23 · LAX 17:23 · JFK 20:23
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.