我在以下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”一词? 感谢您的帮助。
答案 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();
}
在此代码块中,执行以下步骤:
检查thread
是否为null
将client
变量实例化为ChatClientThread
的新实例,并以 this 当前的ChatClient
作为其客户端并将socket
作为其实例插座。
使用其可运行对象实例化该线程,作为 this 当前对象实例。当对象实现接口Runnable
时,该对象必须覆盖public void run()
。 Thread
类实现将执行提供的Runnable的run()
方法。
启动线程。这将执行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();
}
在此代码块中,执行以下步骤:
检查thread
是否为null
将client
变量实例化为ChatClientThread
的新实例,并以 this 当前的ChatClient
作为其客户端并将socket
作为其实例插座。
启动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();
}
}
}
在此代码块中,执行以下步骤:
初始化public ChatClientThread(ChatClient _client, Socket _socket)
{
client = _client;
socket = _socket;
open();
start();
}
变量
初始化client
变量
执行socket
函数。此函数创建DataInputSteam对象,该对象将用于接收输入。
执行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