java thread正常中止的问题:run()中的代码一直在执行,如果中止?

final_ww 2004-01-15 04:21:57
在我们公司开发的系统中,需要连接远程的另外一个系统的socket,现在出现这种问题,远程socket没有响应,可能是没连上,或者是连上了没响应,导致我本地程序等待。为了防止这种等待,我把连接socket的代码放到一个线程中执行,等待时间为3秒,超过3秒,没有返回正确的值,就中止该线程。最直接的方法就是调用stop(),但是jdk1.2以后不推荐使用stop()来强制结束线程,而是希望让线程自己结束,从run()方法return,我也很想这样,但是这个连接socket的过程,可能要一个小时,甚至不会结束,我用什么方法来结束这个线程呢?代码如下
public void run()
{
try
{
socket = new Socket(hostAdd,hostPort);
flag = 1;
}
catch(UnknownHostException ex){
System.out.println("Cannot connect destination host."+ex);
flag = 0;
}
catch (Exception e)
{
System.out.println("Cannot connect destination host."+e);
flag = 0;
}
}
...全文
412 19 打赏 收藏 转发到动态 举报
写回复
用AI写文章
19 条回复
切换为时间正序
请发表友善的回复…
发表回复
hyhu 2004-01-16
  • 打赏
  • 举报
回复
太深入,不太懂!
wlnet 2004-01-16
  • 打赏
  • 举报
回复
你要的应该是Socket的这个方法(jdk1.4):
public void connect(SocketAddress;endpoint,
int;timeout)
dengsf 2004-01-16
  • 打赏
  • 举报
回复
请问 wlnet(W.L) 第二次贴出的代码是哪种语言的?好像不是JAVA……
ActiveJava 2004-01-16
  • 打赏
  • 举报
回复
多线程是java的一个优势,java使得程序员可以很方便的进行多线程程序开发。获得更好的性能。
关于多线程的概念以及一般的多线程编程,比如如何以及为何实现runnable接口,为何stop()会被Deprecated掉等等,这个请看matrix之前的多线程编程基础或者sun的java文档。
关于多线程编程,有几点这里要提到的:
1。既然stop()是不被推荐的,那么我们如何停止一个线程呢?直接kill吗?在这里,笔者总结一种比较通用也比较稳定的方法:

class threadtest extend Thread{
//skip some code..


boolean runflag=true;

public synchronized void stopthread()
{
runflag=false;
}

public synchronized boolean getrunflag()
{
return runflag;
}

public void run() {
runflag=true;
try {
while (getrunflag()) {
code1;
code2;
//put your code here
}
}
}
catch (IOException e) {
e.printStackTrace();
}
System.out.println(this.getClass().getName()+" stopped");
}

//skip some code..
}


这样,每当需要停止该线程时,只需调用stopthread()即可。

这里有两点需要注意:

1)我们用了一个同步方法getrunflag()来得到当前的状态,为什么用这个方法而不是直接使用while(runflag)呢?
这个是因为在java的多线程模型中,有一个公共的对象存储区,但是每个对象都有自己的私有备份,当一个线程改变了状态,jvm并不能保证这个线程改变过的变量即时更新公共对象存储区的状态,可能(可能性不大)造成问题。
所以建议有好的设计习惯,采用同步方法来获得当前的runflag值。

2)还有一点,特别是涉及网络的多线程,如果发生了网络阻塞(在while循环里面发生),那么,即使runflag状态比如改变成false,由于程序被阻塞,线程用这种方法是永远都不会被停止的。
举个例子:比如上面的程序,如果code1是一段网络程式,如果在code1发生了阻塞,阻塞的意义就是得不到请求的
资源,在无限期等待,这个时候,runflag状态的变化对while循环是起不了作用的,线程不会被停止。
笔者曾经参与多个涉及到获取网络资源的java程式,经常遇到因为网络的阻塞引起的线程问题。
如果你的程式可能涉及到网络阻塞,或者有可能发生某种消息接受的阻塞。那么,请不要用这种方法来停止线程。具体方法请看笔者另外一片文章:高级多线程编程(二)-多线程中的监控与超时问题。
79cy 2004-01-16
  • 打赏
  • 举报
回复
没用过,顶一下吧。
wlnet 2004-01-16
  • 打赏
  • 举报
回复
interrupt不行,必须在run()中自己break
tigermaomaolaoliu 2004-01-16
  • 打赏
  • 举报
回复
Thread类中的interrupt方法可以用来终止线程的运行。
<JAVA核心技术卷二>有详细的解释,请参考
final_ww 2004-01-15
  • 打赏
  • 举报
回复
光看是没用,还是要试试,实践出真知嘛!多谢wlnet(W.L)!
Leemaasn 2004-01-15
  • 打赏
  • 举报
回复
没用过,没接触过,友情Up。。。

wlnet 2004-01-15
  • 打赏
  • 举报
回复
connect public void connect(SocketAddress endpoint,
int timeout)
throws IOExceptionConnects this socket to the server with a specified timeout value. A timeout of zero is interpreted as an infinite timeout. The connection will then block until established or an error occurs. Parameters:endpoint - the SocketAddresstimeout - the timeout value to be used in milliseconds. Throws: IOException - if an error occurs during the connection SocketTimeoutException - if timeout expires before connecting IllegalBlockingModeException - if this socket has an associated channel, and the channel is in non-blocking mode IllegalArgumentException - if endpoint is null or is a SocketAddress subclass not supported by this socketSince:1.4
final_ww 2004-01-15
  • 打赏
  • 举报
回复
不对,看错了,如果是though the Socket is still invalid,就可以了,我要的是socket在无效的情况下中止连接
final_ww 2004-01-15
  • 打赏
  • 举报
回复
可以编译通过了,但是这个timeout有用吗?
这是jdk1.4.2的对setTimeout(int)的解释
Enable/disable SO_TIMEOUT with the specified timeout, in milliseconds. With this option set to a non-zero timeout, a read() call on the InputStream associated with this Socket will block for only this amount of time. If the timeout expires, a java.net.SocketTimeoutException is raised, though the Socket is still valid. The option must be enabled prior to entering the blocking operation to have effect. The timeout must be > 0. A timeout of zero is interpreted as an infinite timeout.
从这句话though the Socket is still valid来看,应该是有用的,如果这个可以,就没必要用线程来控制,试试先
wlnet 2004-01-15
  • 打赏
  • 举报
回复
还有 socket.connect(new InetSocketAddress('localhost',8080),3000);
wlnet 2004-01-15
  • 打赏
  • 举报
回复
socket = new Socket();
socket.setSoTimeOut(3000);
socket.connect(new InetSocketAddress('localhost',8080));

应该可以!
final_ww 2004-01-15
  • 打赏
  • 举报
回复
我就怕它自生自灭会锁住socket资源,我们的是在线系统,如果资源被锁住,影响会很大,可是强制stop,也有可能会导致死锁,真是个让我头疼的问题
dengsf 2004-01-15
  • 打赏
  • 举报
回复
刚看了一下《Java2 核心技术》高级特性,它那里也说 Java 对连接的没有限时——(不知高版本的是否有改变)。

如果那样的话,跟楼上的那样处理就行了吧。
ustbzhangwei 2004-01-15
  • 打赏
  • 举报
回复
我也遇到过连接不上时特别耗时间
我基本上也没解决这个问题

只是定了一个时间,对那些耗时的线程过时不侯,不管了,让他自生自灭
final_ww 2004-01-15
  • 打赏
  • 举报
回复
这个只能解决socket连上后,响应的延时,如果都没连上,根本就没用
还有,我查了Socket类的文档,connect方法不能设置port参数,也没找到setPort()方法
wlnet 2004-01-15
  • 打赏
  • 举报
回复
socket = new Socket();
socket.setSoTimeOut(3000);
socket.connect(...)

62,623

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧