[编程][JAVA]在JAVA中如何终止线程中socket.accpet() ? 端口一直被占用
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[编程][JAVA]在JAVA中如何终止线程中socket.accpet() ? 端口一直被占用相关的知识,希望对你有一定的参考价值。
public void run()
ServerSocket serviceSocket = null;
Socket socket = null;
InputStream in = null;
while(true)
try
serviceSocket = new ServerSocket(1234);
socket = serviceSocket.accept();
in = socket.getInputStream();
byte buffer [] = new byte[1024];
int tmp = 0;
while((tmp = in.read(buffer)) != -1)
String result = new String(buffer,0,tmp);
System.out.println(result);
catch (IOException e)
finally
try
if(in != null)
in.close();
if(socket != null)
socket.close();
if(serviceSocket != null)
serviceSocket.close();
catch (IOException e)
如果你是因为程序出错,端口又被占用。可以这样查杀占用端口的进程。。。
netstat -na -o 找到占用1234端口的进程号
taskkill /pid 进程号
这样就可以杀死那个进程了····
如果是要在程序中控制的话,用close方法,然后把那个serverSocket置为null应该就可以了吧。。。
而且楼上说得对,你的程序本来就有问题,serverSocket 的实例话就不应该也在循环里面,估计你是接受到一个客户端以后,new 一个serverSocket ,继续绑定1234端口报错,所以才来提问的。这个是你程序的问题,并不需要去杀死那个什么线程。。。 参考技术A server = new ServerSocket();
server.setReuseAddress(true); //设置 ServerSocket 的选项
server.bind(new InetSocketAddress(port)); //与端口绑定
就可以不怕被占用了~ 参考技术B 多线程,一根负责接收数据包,一根负责关闭serverSocket连接追问
受不了,你可以把我当成一个小白吗?给我一个这样的例子也行,说的太空洞了,风一吹就散了。
追答只是告诉你思路,多线程这个也要写?难道是我说的还不够明白吗?
ServerSocket实例一个就有了,你每次循环都创建了一个实例,有必要吗?
我也知道修改一下
问:如何修改?
并发编程——如何终止线程
前言
今天简单的讲一讲如何终止线程。
如果对于线程的创建方式不太了解,推荐观看并发编程——认识java里的线程
对于线程状态及其切换不了解的,推荐观看并发编程——Java线程的6种状态及切换
对于线程的启动不了解的,推荐观看并发编程——线程的启动
终止线程
终止线程的方式
1、使用标记变量
我们通过继承Thread来创建一个自定义的线程类,里面live这个属性是用来控制线程是否终止
使用main方法去测试,启动线程,然后延迟20毫秒,然后我们去改变这个live,使其跳出循环,继续往下走,执行完run,达到一个线程自然执行完终止的效果。
下面是执行结果,看到结果如我们预想的那样,跳出循环之后,现成终止。
2、使用stop方法
首先看一下stop的源码,我们发现这个方法使用了@Deprecated注解,表示不推荐使用,是被废除的。
这个方法目前还是能够达到终止线程的目的,但是这个方法是不安全的,或者说是比较暴力的中断执行,导致是代码不能执行完,逻辑不完整,而且会释放所有锁资源,影响原子操作,数据不一致问题。所以如果你不知道当前线程的一些执行情况,占用资源的情况的话,还是不推荐使用。
JDK 文档中还引入用一篇文章来解释了弃用这些方法的原因:《Why are Thread.stop, Thread.suspend and Thread.resume Deprecated?》
为什么弃用stop:
- 调用 stop() 方法会立刻停止 run() 方法中剩余的全部工作,包括在 catch 或 finally 语句中的,并抛出ThreadDeath异常(通常情况下此异常不需要显示的捕获),因此可能会导致一些清理性的工作的得不到完成,如文件,数据库等的关闭。
- 调用 stop() 方法会立即释放该线程所持有的所有的锁,导致数据得不到同步,出现数据不一致的问题。
3、使用interrupt方法
跟interrupt在Thread类中相关的有三个方法,分别是interrupt(),interrupted(),isInterrupted()。
下面来分析一下这三个方法的区别,以及用法。
isInterrupted()
通过面向对象思想我们大概就能猜出来,再看到它的返回值是一个boolean类型,那就十之八九能知道这个方法就是获取当前这个中断信号的值是什么。
继续深入点进去发现调用的是一个native本地方法,接收一个是否清除Interrupted标志位的参数,isInterrupted()传递过来的是一个false,说明不会去清除Interrupted标志位。
下面测试结果发现这个方法会在中断线程之后,不会对Interrupted标志位做清除工作,还是true。
interrupted()
首先我们看到这个方法是一个静态方法,interrupted()也调用了isInterrupted(true)方法,不过它传递的参数是true,表示将会清除中断标志位。
下面测试结果发现这个方法会在中断线程之后,会将Interrupted标志位清除,发现清除之后的结果为false。
interrupt()
前面两个是判断是否中断的方法,而interrupt()就是真正触发中断的方法。
中断线程,其实是设置线程的标识位为true。
interrupt()源码:
1、使用isInterrupted()测试代码:
运行结果图:我们发现调用interrupt()之后,标志位变为true,跳出循环,达到一个中断现成的目的。
2、使用interrupted()测试代码:
运行结果图:我们发现调用interrupt()之后,标志位变为true,第二次进入循环,发现不符合,跳出循环,达到一个中断现成的目的。但是使用interrupted()会清除标志位,所以会发现最后一次打印的和之前不一样了,变为false。
这三个方法要搞清楚,这块可能会在面试的时候会问你这三个方法的区别。
感谢诸君的观看,文中如有纰漏,欢迎在评论区来交流。如果这篇文章帮助到了你,欢迎点赞 以上是关于[编程][JAVA]在JAVA中如何终止线程中socket.accpet() ? 端口一直被占用的主要内容,如果未能解决你的问题,请参考以下文章