服务器应用程序:仅适用于println输出

时间:2013-05-15 13:44:21

标签: java multithreading

对于模棱两可的标题道歉 - 我想不出如何用这个来标题。

基本上,我正在使用Java创建一个简单的服务器/客户端程序。我的服务器运行一个线程来不断检查新连接,然后如果找到连接 - 它只为该连接创建一个线程和一个连接对象。

在检查新连接的线程中出现问题 - 它不起作用,直到我开始进行错误检查以及我在行中添加时:

System.out.println("");

它突然开始起作用了。删除此行不会导致为连接添加新线程。我认为它提供了足够的延迟让线程正常运行或者某些东西,所以我放入一个for循环一段时间来看看是否有效 - 但除了那条简单的线之外别无其他。

以下是创建新连接线程的代码:

    class ThreadCreator implements Runnable {

    ThreadCreator() {

    }

    public void run() {
        while(true) {
            System.out.println("WHY DOES THIS WORK??");
            for(int i = 0; i < connections.size(); i++) {
                if(connections.get(i).thread == false) {
                    Runnable ReadRunnable = new Read(connections.get(i));
                    Thread ReadThread = new Thread(ReadRunnable, "MWHAHAH");
                    ReadThread.setPriority(Thread.MAX_PRIORITY);
                    ReadThread.start();
                    connections.get(i).thread = true;
                    System.out.println("THREAD CREATED");
                }
            }
        }
    }
}

我无法想象会出现什么问题......?

2 个答案:

答案 0 :(得分:1)

要记住的一件事是,System.out.println()几乎肯定会涉及同步对某个地方wait()的调用(因为println()通常会刷新并且等待响应可见(或至少传递给其他进程),直到返回。

如果同步是问题,这可以轻松“修复”您的多线程程序。

答案 1 :(得分:1)

感谢Joachim - 我设法解决了这个问题!问题是用于从客户端接收消息的线程和用于查找新连接的线程都访问相同的变量(连接列表)。

我做了一些研究(http://jeremymanson.blogspot.co.uk/2008/11/what-volatile-means-in-java.html)并将volatile修饰符添加到变量中 - 据我所见,确保使用该对象的任何其他线程将被通知它已更改,允许他们同时访问它!

还提到同步线程很重要,变量是由多个线程更改的。但是,我的变量被一个线程读取并被另一个线程更改,所以看起来这里的volatile语句已经足够了!

非常感谢!