【发布时间】:2016-03-30 15:02:48
【问题描述】:
我有以下 Thread 子类(为了便于阅读稍微简化了):
public class ConnectionHandlerThread extends Thread {
private Socket socket;
private volatile boolean disconnected = false;
private ObjectOutputStream out = null;
private ObjectInputStream in = null;
public ConnectionHandlerThread(Socket socket){
this.socket = socket;
}
public void run(){
disconnected = false;
try {
out = new ObjectOutputStream(socket.getOutputStream());
in = new ObjectInputStream(socket.getInputStream());
while(!disconnected){
try{
Object data = in.readObject();
}
catch(ClassNotFoundException e){
// Handle exception
}
catch(IOException e){
// Handle exception
}
}
}
catch (IOException e) {
// Handle exception
}
}
public void send(Object data){
try{
out.writeObject( data );
}
catch(IOException e){
// Handle exception
}
}
}
当我连接到服务器时,我的客户端(使用 Swing GUI)创建了这个线程的一个实例。我觉得奇怪的是,我可以从主 GUI 调用方法 send(Object data),它可以工作。为什么无限的while循环和/或对in.readObject()的调用不会阻止我这样做?我的意思是线程不应该一直忙于做其他事情吗?这是做事的好方法吗?如果不是,为什么不呢?
编辑
澄清令我困惑的地方:如果这是在主线程中,它将在in.readObject() 上忙,直到读取某些内容,然后它会在循环的下一次迭代中再次开始侦听。当然,我知道我可以从另一个线程调用send()。但让我大吃一惊的是——“谁”实际上正在执行send()?是我的线程在做,还是调用线程在做?如果是前者,怎么可能既忙于等待while循环中的输入又执行send()方法呢?我只是很难把我的想法包裹起来......
【问题讨论】:
-
因为您正在传递您在主 GUI Swing 中创建的套接字的引用...
-
请详细说明一下...
-
这听起来好像你对线程是什么感到困惑。当您尚未在两个线程之间建立任何同步时,为什么您会期望一个线程的活动(例如,从
in读取)会干扰其他线程的活动(例如,写入out)?线程彼此独立运行,除非它们在相同的同步对象上运行。 -
查看我回答中的示例
-
@jameslarge 是的,我现在很困惑。我以为我了解线程是什么,但现在我不再了解了:) 我认为让我感到困惑的是
send()方法是在ConnectionHandlerThread中定义的。换句话说——如果我在主线程上做in.read(),UI 会冻结。所以让我困惑的是为什么ConnectionHandlerThread不是“冻结”,即为什么它可以执行send(),同时在run()中被in.read()阻止。我想这是一个愚蠢的问题,但除非有人以一种好的方式解释它,否则我想我只会感到困惑。
标签: java multithreading swing runnable java-threads