Java:启动线程的方法

时间:2018-08-16 11:54:10

标签: multithreading

我在以下link处找到了建立简单Java聊天的基础:

基本上,ChatClient使用以下代码启动ChatClientThread:

if (thread == null)
  {  client = new ChatClientThread(this, socket);
     thread = new Thread(this);                   
     thread.start();
  }

有人可以帮助我了解上述代码与此代码之间的区别吗?

 if (thread == null)
{  client = new ChatClientThread(this, socket);                   
 client.start();
}

是仅将线程设置为!= null还是有特定原因?在这种情况下,“客户端”线程如何传递给新线程并带有“ this”一词? 感谢您的帮助。

2 个答案:

答案 0 :(得分:1)

摘要

简短的回答是,一个带有thread.start()的线程创建了2个线程,一个带有client.start()的线程创建了1个线程,可能抛出了IllegalThreadStateException

为充分说明这种情况,我将问题分为三个部分: thread.start()代码,client.start()代码和ChatClientThread实例化。


第1部分-thread.start()

if (thread == null)
{  
    client = new ChatClientThread(this, socket);
    thread = new Thread(this);                   
    thread.start();
}

在此代码块中,执行以下步骤:

  1. 检查thread是否为null

  2. client变量实例化为ChatClientThread的新实例,并以 this 当前的ChatClient作为其客户端并将socket作为其实例插座。

  3. 使用其可运行对象实例化该线程,作为 this 当前对象实例。当对象实现接口Runnable时,该对象必须覆盖public void run()Thread类实现将执行提供的Runnable的run()方法。

  4. 启动线程。这将执行ChatClient的相应run()方法,因为我们在线程runnable时实例化了该线程。

以下是thread.start()要执行的操作:

public void run() 
{  
    while (true) 
    {  
        try 
        {  
            streamOut.writeUTF(console.readLine());
            streamOut.flush();
        }
        catch(IOException ioe) 
        {
            System.out.println("Sending error: " + ioe.getMessage());
            stop();
        }
    }
}

第2部分-client.start()

if (thread == null)
{  
    client = new ChatClientThread(this, socket);                   
    client.start();
}

在此代码块中,执行以下步骤:

  1. 检查thread是否为null

  2. client变量实例化为ChatClientThread的新实例,并以 this 当前的ChatClient作为其客户端并将socket作为其实例插座。

  3. 启动ChatClientThread。这将执行ChatClientThread的{​​{1}}方法。

以下是run()要执行的代码:

client.start()

第3部分-ChatClientThread实例化

现在,ChatClientThread构造函数包含一些需要注意的重要代码。

public void run() 
{  
    while (true) 
    {  
        try 
        {  
            client.handle(streamIn.readUTF());
        }
        catch(IOException ioe) 
        {
            System.out.println("Listening error: " + ioe.getMessage());
            client.stop();
        }
    }
}

在此代码块中,执行以下步骤:

  1. 初始化public ChatClientThread(ChatClient _client, Socket _socket) { client = _client; socket = _socket; open(); start(); } 变量

  2. 初始化client变量

  3. 执行socket函数。此函数创建DataInputSteam对象,该对象将用于接收输入。

  4. 执行open()函数。此函数将启动start()实例并执行其各自的ChatClientThread方法。请注意,此时run()的当前状态正在运行。如果我们看一下第2部分的代码,我们会看到在初始化ChatClientThread变量client之后,就执行了。由于线程两次启动,因此可能会抛出client.start()。一旦启动,就无法在线程上再次调用start。

以下是IllegalThreadStateException要执行的操作:

start()

结论

第1部分中,应用程序将创建2个线程;一个是运行自己的public void run() { while (true) { try { client.handle(streamIn.readUTF()); } catch(IOException ioe) { System.out.println("Listening error: " + ioe.getMessage()); client.stop(); } } } 方法的ChatClientThread,另一个是运行run()的{​​{1}}方法的thread变量。

第2部分中,应用程序将创建1个线程; ChatClient运行自己的run()方法。 ChatClientThread函数可能会抛出run(),因为client.start()将被启动两次。

答案 1 :(得分:0)

if(thread == null)
{
  client = new ChatClientThread(this, socket);
  thread = new Thread(this);
  thread.start();
}

if(thread == null)
{
  client = new ChatClientThread(this, socket);
  client.start();
}

Here you need to aware about the following things

first "this" => this is keyword in java which returns running instance of class
second "ChatClientThread" => ChatClientThread declared as follows

"public class ChatClientThread extends Thread " that means ChatClientThread is child class of Thread class.

So in first block we are passing Runnable object(this) to the ChatClientThread which will then pass to thread,=> client = new ChatClientThread(this, socket);
and in next statement we are passing Runnable object(this) to the thread itself.=>
 thread = new Thread(this);
So in first block we are having two runnable instance that can be run
and in second we have only one ie. customized ChatClientThread