代码之家  ›  专栏  ›  技术社区  ›  Alex

Java套接字的PrintWriter线程安全吗?

  •  9
  • Alex  · 技术社区  · 17 年前

    所以,我有两条线。

    线程1管理客户端连接。(只有一台客户端和一台服务器)
    我称之为我的服务器线程。

    线程2管理向客户端发送消息。我称之为我的消息处理器线程。

    线程一负责定期向客户机发送心跳信号。

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

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

    在这些假设下,我编写了这个函数来发送心跳:

    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();
            }
        }
    

    另一个线程,即“处理器”线程,其功能类似于:

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

    以这种方式,每当我希望发送心跳时,我都会创建一个新的“缓冲区”,我的消息永远不会被覆盖。

    DSGDSBG#sdg

    这将导致稍后发生堆芯转储。

    以下是我的问题:

    1) 套接字显然不是线程安全的,但是我从它们那里得到的PrintWriter是线程安全的吗?或者它只是返回同一个PrintWriter?

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

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

    2 回复  |  直到 17 年前
        1
  •  11
  •   Tom Hawtin - tackline    17 年前

    这是一个糟糕的设计,有这么多 PrintWriter

    但是,假设出于某种原因您确实需要多个 字符打印流

    第一个问题: Writer this 字符打印流 BufferedWriter 作家 它们的构造与锁相同。这显然是完全失败的。他们应该使用 作家 是锁,不是锁 作家 它本身一个很容易犯的错误,因为具有 Object 消除静态类型的安全性。所以你需要构造一个 字符打印流 用插座 OutputStream (或其他一些普通物体)作为锁。

    字符打印流 print flush

    所以,事实并非如此 意味深长 线程安全,但你可以破解它。或者你可以使用更好的设计。

        2
  •  5
  •   C. K. Young    17 年前

    你需要一种方法来使用同样的方法 PrintWriter 在线程之间( t1.writer == t2.writer ,不只是 它是由相同的元素创建的 OutputStream 字符打印流 ,则所有写入操作都是同步的。

    推荐文章