简体   繁体   English

Java线程非法状态异常

[英]Java thread illegal state exception

In a pice of code in which a class start a thread calling start method.在一段代码中,一个类启动了一个调用 start 方法的线程。

it throw an illegalstate exception.它抛出一个非法状态异常。 But if i call run() it gose well.但是如果我调用 run() ,它运行良好。

Can you expain me why ?你能解释一下为什么吗?

class A{


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

}

class T extends Thread{

....

....

}

real code:真实代码:

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

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

Well, if you call run() , you're just calling a method in your current thread. 好吧,如果您调用run() ,那么您只是在当前线程中调用一个方法。 With start() you're attempting to start the Thread , and if it has for example already been started (or it has already stopped), you'll get an IllegalStateException . 使用start()尝试启动Thread ,例如,如果它已经启动(或已经停止),则将收到IllegalStateException

嗯...您已经在构造函数中启动了WDAgent Thread ,因此当您尝试再次启动它时,它会阻塞IllegalStateException

You wanted to start it here: 您想从这里开始:

...
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) {
...

But it was started in the constructor: 但这是在构造函数中启动的:

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!!!!
}

You are running the run method twice, once in the new thread (you start it in the constructor) and one in the main thread by calling run. 您将运行run方法两次,一次在新线程中(在构造函数中启动),一次在主线程中通过调用run。

t.start() is used to start the thread's execution. t.start()用于启动线程的执行。 t.start() is used one time only. t.start()只使用一次。 If you want to a run the thread again you will need to use t.run() .如果您想再次运行该线程,则需要使用t.run()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM