Java线程非法状态异常

时间:2013-11-27 09:05:46

标签: java multithreading

在一个代码中,一个类启动一个调用start方法的线程。

它抛出非法状态异常。但如果我打电话给run(),那就很好了。

你可以告诉我为什么吗?

class A{


void methodA(){
   T t = new T();
    t.start();     // illegal state exception
    t.run();  ///ok 
}

}

class T extends Thread{

....

....

}

真实代码:

  public class FileMultiServer
 {
  private static Logger _logger = Logger.getLogger("FileMultiServer");

  public static void main(String[] args) 
  {

 ServerSocket serverSocket = null;
 boolean listening = true;

 String host = "localhost";
 int porta = 4444;
 InetSocketAddress addr = null;
 String archiveDir = System.getProperty("java.io.tmpdir");

 Aes aes = new Aes();

 Properties prop = new Properties();
 //load a properties file
 File propFile = new File("config.properties");
 try {
    System.out.println(propFile.getCanonicalPath());
     prop.load(new FileInputStream("config.properties"));

 } catch (Exception e1) {
    // TODO Auto-generated catch block
    System.out.println(e1);
 }


 DBConnector.dbName = prop.getProperty("database");
 DBConnector.ipDb = prop.getProperty("urlDb");
 DBConnector.dbPort = prop.getProperty("dbport");
 DBConnector.userName = prop.getProperty("dbuser");
 DBConnector.password = aes.DeCrypt(prop.getProperty("dbpassword"));         

 String agent_address = prop.getProperty("agent_ip");
 String agent_port = prop.getProperty("agent_port");

 try {
    WDAgent m_agent = new WDAgent(agent_address, Integer.parseInt(agent_port));
    m_agent.run();
} catch (NumberFormatException e1) {
    // TODO Auto-generated catch block
    System.out.println("errore nell'agent");
    e1.printStackTrace();
} catch (Exception e1) {
    // TODO Auto-generated catch block
    StringWriter errors = new StringWriter();
    e1.printStackTrace(new PrintWriter(errors));
    _logger.debug(e1.getMessage());
    _logger.debug(errors.toString());
    System.out.println(e1.getMessage());
    System.out.println(errors.toString());
} 



 String logCfg = System.getProperty("LOG");
 if (logCfg != null) DOMConfigurator.configure(logCfg); else
   DOMConfigurator.configure("log4j.xml");
 try
 {
   if (args.length == 0) {
     host = "localhost";
     porta = 4444;
   }
   else if (args.length == 1) {
     porta = Integer.parseInt(args[0]);
   } else if (args.length == 2) {
     host = args[0];
     porta = Integer.parseInt(args[1]);
   } else if (args.length == 3) {
     host = args[0];
     porta = Integer.parseInt(args[1]);
     archiveDir = args[2];
   } else {
     _logger.info("usage: server <host> <port> | server [port] | server");
     System.exit(88);
   }
 } catch (Exception e) {
   _logger.error(e.getMessage());
   _logger.info("enter a numer for argument or nothing....");
   System.exit(88);
 }

 _logger.info("Allocating listen to: " + host + ":" + porta);
 try
 {
   addr = new InetSocketAddress(host, porta);
   serverSocket = new ServerSocket();
   serverSocket.bind(addr);
 } catch (Exception e) {
   _logger.error(e.getMessage());
   _logger.error("Could not listen on port: " + porta);
   System.exit(-1);
 }

 _logger.info("Server listening on " + host + "-" + addr.getAddress().getHostAddress() + ":" + porta);
 while (listening) {
   try {
    new FileMultiServerThread(serverSocket.accept(), archiveDir).start();
    } catch (Exception e) {
        // TODO Auto-generated catch block
        System.out.println(e);
    }
 }
 try {
    serverSocket.close();
} catch (Exception e) {
    // TODO Auto-generated catch block
    System.out.println(e);
}
  }
 }

类扩展thread:

  public class WDAgent extends Thread 
  {
private  String _PID=null;
// *************************************************************************
// private - static final
// *************************************************************************
DatagramSocket socket;
boolean m_shutdown = false;

private static final Logger m_logger = Logger.getLogger(WDAgent.class);

private String getPID() {
    try {
        String ppid=System.getProperty("pid");
        String match= "-Dpid="+ppid;
        Runtime runtime = Runtime.getRuntime();
        String cmd="/bin/ps -ef ";
        Process process = runtime.exec(cmd);
        InputStream is = process.getInputStream();
        InputStreamReader osr = new InputStreamReader(is);
        BufferedReader br = new BufferedReader(osr);
        String line;
        while ((line = br.readLine()) != null) {
             m_logger.info("line 0: "+line);    
             if(line.indexOf(match)!=-1 ) {
             m_logger.info("line: "+line);
             String[] cols=line.split(" ");
             int count=0;
             String val=null;
             for (int k=0; k<cols.length; k++) {
                  if(cols[k].length()==0) continue;
                  count++;
                  if(count==3) {
                      // Good. I answerd the question
                      String pid =  val;
                      m_logger.debug("pid processo: " + pid);
                      return pid;
                     }
                  val=cols[k];
              }
            }
        }
    } 
    catch (Exception err) 
    {
        m_logger.error("Error retrieving PID....", err);
        err.printStackTrace();
    } 

    return null;
}

public WDAgent(String address, int port) throws IOException
{
    InetSocketAddress isa = new InetSocketAddress(address, port);
    socket = new DatagramSocket(isa);
    m_logger.info("Agent started on (" + address + ":" + port + ")");
    m_logger.info("Waiting for WD connection.");

    this.start();
}

void Finalize() throws IOException 
{
    m_logger.info("Closing Agent.");
    socket.close();
    m_logger.info("Agent Closed");
}

public void Shutdown()
{
    m_shutdown = true;
}

public void run() 
{
    byte[] buffer = new byte[1024];
    int i;

    while(!m_shutdown) 
    {
        try {
            String answer = "Agent PID=123456";
            for (i=0; i<1024; i++)
                buffer[i] = 0;

            DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
            socket.receive(packet);
            String received = new String(packet.getData(), 0, packet.getLength());

            InetAddress client = packet.getAddress();
            int client_port = packet.getPort();
            m_logger.info("Received " + received + " from " + client);

            if ((received.indexOf("PID") > 0) && (received.indexOf("ASK") > 0))
            {
                if(_PID==null) {
                    _PID=getPID();
                }
                if(_PID!=null) {
                     answer = "Agent PID=" + _PID;
                     m_logger.debug("risposta: " + answer);
                     DatagramPacket answ_packet = new DatagramPacket(answer.getBytes(), answer.getBytes().length, client, client_port);
                     socket.send(answ_packet);
                } else {
                    m_logger.error("no PID per rispondere a watchdog .... sorry");
                }
            }
            else
                m_logger.warn("Command not recognized");
        } 
        catch(IOException e) 
        {
            m_logger.error(e.getMessage());
        }
        catch(Exception e) 
        {
            m_logger.error(e.getMessage());
        }
    }
}
  }

3 个答案:

答案 0 :(得分:6)

好吧,如果你打电话给run(),你只是在当前线程中调用一个方法。使用start(),您尝试启动Thread,如果它已经启动(或已经停止),您将获得IllegalStateException

答案 1 :(得分:1)

嗯......你已经在构造函数中启动了WDAgent Thread,所以当你试图再次启动它时,它会IllegalStateException

答案 2 :(得分:0)

你想在这里开始:

...
try {
    WDAgent m_agent = new WDAgent(agent_address, Integer.parseInt(agent_port));
    m_agent.run(); // <-- Run that you wanted to be a start
} catch (NumberFormatException e1) {
...

但它是在构造函数中启动的:

public WDAgent(String address, int port) throws IOException
{
    InetSocketAddress isa = new InetSocketAddress(address, port);
    socket = new DatagramSocket(isa);
    m_logger.info("Agent started on (" + address + ":" + port + ")");
    m_logger.info("Waiting for WD connection.");

    this.start(); // <<----- It was already started here!!!!
}

您正在运行run方法两次,一次在新线程中(在构造函数中启动它),在主线程中通过调用run运行一次。