Java套接字的PrintWriter线程是否安全? [英] Is a Java socket's PrintWriter thread safe?

查看:122
本文介绍了Java套接字的PrintWriter线程是否安全?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以,我有两个主题。

So, I have two threads.

线程一管理客户端连接。 (只有一个客户端和一个服务器)

我将其称为我的服务器线程。

Thread one manages the client connections. (There is only one client and one server)
I call it my server thread.

线程二管理向客户端发送消息。我将其称为我的消息处理器线程。

Thread two manages sending messages to the client. I call it my message processor thread.

线程1负责,其中包括定期向客户端发送心跳。

Thread one is responsible, among other things sending a heartbeat to the client periodically.

编程时我假设套接字不是线程安全的,但缓冲区是,只要我使用单独的缓冲区用于服务器和处理器线程我没事。

When programming I made an assumption that the sockets weren't thread safe, but the buffers were, and as long as I was using seperate buffers for the server and processor threads I would be fine.

我还假设PrintWriter类似于Java中的套接字缓冲区。

I also made the assumption that the "PrintWriter" was analogous to the socket buffer in Java.

根据这些假设,我写了这个函数来发送心跳:

Under these assumptions I wrote this function to send a heartbeat:

public void sendHeartBeat(){
        logger.info("Sending a hearbeat!");
        PrintWriter printWriter=null;
        try {
            printWriter = new PrintWriter(clientSocket.getOutputStream());
        } catch (IOException e) {
            logger.info(e.toString());
        }
        if(printWriter!=null){
            printWriter.print("HEARTBEAT#");
            printWriter.flush();
        }
    }

另一个线程,处理器做一件事类似的是:

The other thread, the "processor" one does something similar in that it does:

printWriter=new PrintWriter(theServer.getClientSocket().getOutputStream());

这样我每次希望发送心跳时都会创建一个新的缓冲区,我的消息永远不会被覆盖。

In this manner I would create a new "buffer" every time I wished to send a heartbeat, and my messages would never get overwritten.

不幸的是,情况似乎并非如此。我收到一条消息来自管道:
dsgdsbHEARTBEAT #sdg

Unfortuneately this does not seem to be the case. And I get an message coming through the pipe like this: dsgdsbHEARTBEAT#sdg

这会导致稍后的核心转储。

This causes a core dump later.

以下是我的问题:

1)套接字显然不是线程安全的,但是我从它们获得的PrintWriters是否安全?或者只是返回相同的PrintWriter?

1) Sockets are obviously not thread safe, but are the PrintWriters I get from them thread safe? Or is it just returning the same PrintWriter?

2)什么类似于Java中的套接字缓冲区?我该如何看待这个问题?

2) What is analogous to the socket buffer in Java? How should I think about this problem?

3)如何使这些线程不写入套接字上的同一个缓冲区?

3) How do I make it so that these threads do not write to the same buffer on the socket?

推荐答案

设置这些多个 PrintWriter 的设计很糟糕相同的流。真的,你至少想要调用它们的对象(或线程受限)。

It's a poor design to have these multiple PrintWriters on the same stream. Really you want at least the object the calls them to be synchronised (or thread confined).

但是,假设由于某种原因你确实需要多个 PrintWriter s:

However, assuming for some reason you do want multiple PrintWriters:

第一个问题: Writer s不使用这个作为锁。 PrintWriter BufferedWriter 默认情况下都使用 Writer 它们是用锁作为构造。这显然完全被打破了。他们应该使用 Writer 的锁,而不是 Writer 本身。锁定 Object 功能的一个简单错误是删除静态类型安全性。因此,您需要使用套接字 OutputStream (或其他一些常见对象)构造 PrintWriter 作为锁。

First problem: Writers do not use this as the lock. PrintWriter and BufferedWriter by default both use the Writer they are constructed with as the lock. This is obviously completely broken. They should be using the Writer's lock, not the Writer itself. An easy mistake given that having locking a feature of Object removes static type safety. So you'll need to construct a PrintWriter with the socket OutputStream (or some other common object) as the lock.

其次,我们在 PrintWriter 内进行缓冲。因此,缓冲区结束,写入一半,等待下一次写入。要防止这种情况,要么外部锁定以组合打印刷新,要么使用自动刷新并添加新行字符。

Secondly, we have buffering within PrintWriter. So come the end of a buffer, half get written and half wait for the next write. To prevent that, either externally lock to combine a print and flush, or use auto-flushing and add a new line character.

因此,它不是有意义的线程安全,但你可以破解它。或者你可以使用更好的设计。

So, it isn't meaningfully thread-safe, but you can hack it. Or you can use a better design.

这篇关于Java套接字的PrintWriter线程是否安全?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆