主动式关闭-线程,ServerSocket堵塞关闭的一个法子

2024-03-07 12:32

本文主要是介绍主动式关闭-线程,ServerSocket堵塞关闭的一个法子,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

在Java上,启动一个线程容易,让一个线程不断运行,也很容易,只要一个while循环,一直做死循环就行了。不过问题来了,那关闭线程怎么办?

 

先写个例子:

 

public class TestThread extends Thread {@Overridepublic void run() {while(true){System.out.println("一直运行");try {sleep(3000);} catch (InterruptedException e) {e.printStackTrace();}}}
}

 这样就可以让线程一直运行了,没错,这样是可以,让线程关闭的最好方法不是使用destroy方法,而是让线程自己结束。这个就是主动式关闭。所以一般都是这样处理一个线程:

 

public class TestThread extends Thread {private boolean flag = true;@Overridepublic void run() {while(flag){System.out.println("一直运行");try {sleep(3000);} catch (InterruptedException e) {e.printStackTrace();}}}public void stopThread(){this.flag = false;}
}

 当这个线程正在运行时,可以用别的线程调用 stopThread()方法,这个时候flag就变成了false,循环结束,线程也就停止了!不过问题又来了,如果是线程里面是这样子的:你看怎么解决?

 

package cn.std.run.monitor;import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;public class TestThread extends Thread {private boolean flag = true;@Overridepublic void run() {try {ServerSocket serverSocket = new ServerSocket(50001);Socket socket = null;while (flag) {socket = serverSocket.accept();//SocketCtrlHandler.processRequest(socket);此处对Socket处理}} catch (IOException e) {e.printStackTrace();}}public void stopThread(){this.flag = false;}
}

 这个时候,stopThread方法就不行了,因为在

 

socket = serverSocket.accept();

 处,程序会一直堵塞,就像是在循环里面停止了一样,只有等到新的Socket连接进来了,才能不再堵塞。

于是解决办法又有了:

 

package cn.std.run.monitor;import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.UnknownHostException;public class TestThread extends Thread {private boolean flag = true;@Overridepublic void run() {try {ServerSocket serverSocket = new ServerSocket(50001);Socket socket = null;while (flag) {socket = serverSocket.accept();//SocketCtrlHandler.processRequest(socket);此处对Socket处理}} catch (IOException e) {e.printStackTrace();}}public void stopThread(){this.flag = false;try {new Socket("localhost",50001);} catch (UnknownHostException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}}public static void main(String[] args) throws InterruptedException {TestThread tt = new TestThread();tt.start();sleep(3000);tt.stopThread();}
}

 在stopThread方法里面new Socket,让线程不再堵塞,进入下一个循环,但是进入下一个循环判断的时候已经变为false,循环结束,线程停止!

 

那再来一个例子,线程等待队列:

 

package cn.std.run.monitor;import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.LinkedList;public class TestThread extends Thread {private boolean flag = true;private LinkedList<Object> pool = new LinkedList<Object>();public void add(Object obj){synchronized (pool) {pool.add(obj);pool.notify();}}@Overridepublic void run() {Object obj = null;while(flag){synchronized (pool) {while(pool.isEmpty()){try {pool.wait();} catch (InterruptedException e) {e.printStackTrace();}}obj = pool.remove(0);}dispose(obj);}}public void dispose(Object obj){System.out.println(obj);}public void stopThread(){this.flag = false;}public static void main(String[] args) throws InterruptedException {TestThread tt = new TestThread();tt.start();sleep(3000);tt.stopThread();}
}

 这是一个经常使用的线程排队,如果这时候stopThead不做特殊处理,也不能成功关闭线程,

得这样才行:

 

public void stopThread(){this.flag = false;add("");}

 原理跟上面的ServerSocket堵塞一样,这个就是我说的主动式关闭!好吧,再加一句,原谅我菜,呵呵~~

这篇关于主动式关闭-线程,ServerSocket堵塞关闭的一个法子的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/783531

相关文章

怎么关闭Ubuntu无人值守升级? Ubuntu禁止自动更新的技巧

《怎么关闭Ubuntu无人值守升级?Ubuntu禁止自动更新的技巧》UbuntuLinux系统禁止自动更新的时候,提示“无人值守升级在关机期间,请不要关闭计算机进程”,该怎么解决这个问题?详细请看... 本教程教你如何处理无人值守的升级,即 Ubuntu linux 的自动系统更新。来源:https://

Springboot的ThreadPoolTaskScheduler线程池轻松搞定15分钟不操作自动取消订单

《Springboot的ThreadPoolTaskScheduler线程池轻松搞定15分钟不操作自动取消订单》:本文主要介绍Springboot的ThreadPoolTaskScheduler线... 目录ThreadPoolTaskScheduler线程池实现15分钟不操作自动取消订单概要1,创建订单后

Springboot使用RabbitMQ实现关闭超时订单(示例详解)

《Springboot使用RabbitMQ实现关闭超时订单(示例详解)》介绍了如何在SpringBoot项目中使用RabbitMQ实现订单的延时处理和超时关闭,通过配置RabbitMQ的交换机、队列和... 目录1.maven中引入rabbitmq的依赖:2.application.yml中进行rabbit

C语言线程池的常见实现方式详解

《C语言线程池的常见实现方式详解》本文介绍了如何使用C语言实现一个基本的线程池,线程池的实现包括工作线程、任务队列、任务调度、线程池的初始化、任务添加、销毁等步骤,感兴趣的朋友跟随小编一起看看吧... 目录1. 线程池的基本结构2. 线程池的实现步骤3. 线程池的核心数据结构4. 线程池的详细实现4.1 初

Ubuntu 24.04 LTS怎么关闭 Ubuntu Pro 更新提示弹窗?

《Ubuntu24.04LTS怎么关闭UbuntuPro更新提示弹窗?》Ubuntu每次开机都会弹窗提示安全更新,设置里最多只能取消自动下载,自动更新,但无法做到直接让自动更新的弹窗不出现,... 如果你正在使用 Ubuntu 24.04 LTS,可能会注意到——在使用「软件更新器」或运行 APT 命令时,

Go信号处理如何优雅地关闭你的应用

《Go信号处理如何优雅地关闭你的应用》Go中的优雅关闭机制使得在应用程序接收到终止信号时,能够进行平滑的资源清理,通过使用context来管理goroutine的生命周期,结合signal... 目录1. 什么是信号处理?2. 如何优雅地关闭 Go 应用?3. 代码实现3.1 基本的信号捕获和优雅关闭3.2

Java子线程无法获取Attributes的解决方法(最新推荐)

《Java子线程无法获取Attributes的解决方法(最新推荐)》在Java多线程编程中,子线程无法直接获取主线程设置的Attributes是一个常见问题,本文探讨了这一问题的原因,并提供了两种解决... 目录一、问题原因二、解决方案1. 直接传递数据2. 使用ThreadLocal(适用于线程独立数据)

线程的四种操作

所属专栏:Java学习        1. 线程的开启 start和run的区别: run:描述了线程要执行的任务,也可以称为线程的入口 start:调用系统函数,真正的在系统内核中创建线程(创建PCB,加入到链表中),此处的start会根据不同的系统,分别调用不同的api,创建好之后的线程,再单独去执行run(所以说,start的本质是调用系统api,系统的api

C#关闭指定时间段的Excel进程的方法

private DateTime beforeTime;            //Excel启动之前时间          private DateTime afterTime;               //Excel启动之后时间          //举例          beforeTime = DateTime.Now;          Excel.Applicat

java线程深度解析(六)——线程池技术

http://blog.csdn.net/Daybreak1209/article/details/51382604 一种最为简单的线程创建和回收的方法: [html]  view plain copy new Thread(new Runnable(){                @Override               public voi