为什么这段代码会冻结我的电脑?

时间:2012-07-10 16:26:32

标签: java io client-server server-side

这是如此糟糕,我必须进行硬重启(按住电源按钮),它甚至没有给我时间调试,所以如果我在这里没有得到答案,我基本上搞砸了。我知道它是服务器端(因为它发生在我不运行客户端时,但如果我这样做也会发生)。

这是服务器代码:

package cypri.games.cybatarserver;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Vector;

import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;

public class CybatarServer extends JFrame implements Runnable{
    String verNum = "0.0.0";
    JScrollPane jsp;
    JTextArea mainText;
    boolean stopServer = false;
    boolean waitForPlayers = true;
    Vector<Player> playersConnected;
    byte playerID = -1;

    public CybatarServer(){
        playersConnected = new Vector<Player>();

        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setBounds(100, 100, 400, 100);

        this.setTitle("Cybatar Server " + verNum);

        mainText = new JTextArea(50, 10);
        mainText.setText("Welcome to CybatarServer "+ verNum + "!\n");
        mainText.setEditable(false);

        jsp = new JScrollPane(mainText);
        this.add(jsp);

        this.setVisible(true);
    }

    public static void main(String[] args){
        CybatarServer cyserv = new CybatarServer();
        cyserv.run();
    }

    @Override
    public void run() {

        try { 
            final ServerSocket serverSocket = new ServerSocket(44444);


            while(!stopServer){
                if(waitForPlayers){
                    new Thread(new Runnable() {
                        public void run() {

                            Socket clientSocket = null;
                                try {
                                    clientSocket = serverSocket.accept();
                                } catch (IOException e) {
                                    // TODO Auto-generated catch block
                                    e.printStackTrace();
                                }
                                playerID++;
                                new PlayerThread(playerID, playersConnected, mainText, playerID, clientSocket).start();
                                mainText.append("Player " + playerID + " connected!");

                        }
                    }).start();
                }

                else{
                    for(int i = 0; i < playersConnected.size(); i++){
                        playersConnected.get(i).update();
                    }
                }

                Thread.yield();
            }
        } catch (Exception e) { e.printStackTrace(); }
    }
}

这里有什么东西可以导致我的电脑完全冻结吗?如果是这样,我该如何解决?

4 个答案:

答案 0 :(得分:11)

我怀疑

while(!stopServer){
   if(waitForPlayers){
       new Thread(new Runnable() {
         ....

正在生成并调用大量线程。这会在CPU(运行这些线程)和内存(每个线程分配自己的堆栈空间)方面严重影响你的机器。

我怀疑你想接受传入的连接而只有才能分配/启动一个线程。请注意,这仍然会让您受到DOS攻击(想象一下,如果有无限数量的玩家加入),但这对您来说可能不是一个实际问题。

答案 1 :(得分:3)

旁注:run UI stuff in the UI thread

这部分:

while(!stopServer){
    if(waitForPlayers){
         new Thread(...).start();
     }
}

将创建大量线程,除非stopServer或waitForPlayers标志更快地更改。毫不奇怪它挂起......

答案 2 :(得分:2)

您似乎永远不会将waitForPlayers设置为false。因此,每次while(!stopServer)循环时,您都会生成一个新线程,从而冻结您的计算机。

答案 3 :(得分:1)

显然没有尝试过运行它,但是这个结构让我觉得它是一个潜在的叉炸弹:

              new Thread(new Runnable() {
                    public void run() {
                            ...
                            new PlayerThread(playerID, playersConnected, mainText, playerID, clientSocket).start();
                            ...
              }