`

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

阅读更多

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

 

先写个例子:

 

public class TestThread extends Thread {
	@Override
	public 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;
	@Override
	public 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;
	@Override
	public 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;
	@Override
	public 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();
		}
	}
	
	@Override
	public 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

    首先,`ServerSocket`的`close()`方法是一个关键操作,它的主要作用是让服务器释放占用的端口,并终止与所有已建立连接的客户端的连接。执行`close()`方法后,任何尝试连接到此`ServerSocket`的客户端请求都将被拒绝...

    Java Socket学习---单线程阻塞

    在这个场景中,服务器端通过一个线程处理一个客户端的请求,当请求被处理时,该线程会处于阻塞状态,直到客户端发送的数据被完全接收并响应。这种方式虽然简单,但可能无法有效应对大量并发连接。 首先,我们来看`...

    Java Socket学习---多线程阻塞

    同时,为了处理多个并发连接,我们通常会为每个连接创建一个新的线程,这样就可以在不中断其他连接的情况下服务新的客户端。 接下来是`SocketUtils.java`。这个文件可能包含了通用的Socket操作工具方法,例如创建...

    Java多线程_ServerSocket服务端与客户端通信案例

    Java多线程环境下使用ServerSocket和Socket进行服务端与客户端之间的通信是一个经典的网络编程模型。在这个模型中,服务端使用ServerSocket类监听特定端口,等待客户端的连接请求。而客户端则通过Socket类建立与...

    socket-ServerSocket例子

    `ServerSocket`是Java中的服务器端套接字类,它允许服务器创建一个监听特定端口的套接字,等待客户端的连接请求。`ServerSocket`的基本用法如下: ```java import java.net.ServerSocket; import java.io....

    serversocket单线程跟多线程例子

    以下是一个简单的单线程`ServerSocket`示例: ```java import java.net.ServerSocket; import java.net.Socket; public class SingleThreadServer { public static void main(String[] args) throws Exception { ...

    ClientSocket-and-ServerSocket.rar_Delphi ServerSocket_ServerSock

    一旦有连接请求到来,`ServerSocket`就会创建一个新的`ClientSocket`对象来处理这个连接,允许服务器与客户端进行数据交换。 `ClientSocket`则是客户端的网络组件,用于建立到远程服务器的连接。开发者可以通过设置...

    Java Socket/ServerSocket 多线程下聊天室系统

    在聊天室系统中,每个连接的客户端都会创建一个新的线程,以便服务器可以同时处理来自不同客户端的请求,避免了单线程模型下的阻塞问题。例如,当一个客户端发送消息时,其他客户端可以同时接收和发送信息,保持系统...

    socket-serversocket

    创建一个ServerSocket实例时,你需要指定一个端口号。一旦创建,ServerSocket就会阻塞,直到有客户端尝试连接到该端口。例如: ```java ServerSocket serverSocket = new ServerSocket(8080); ``` 当一个连接请求...

    javaSocket的Tcp通信方式两个线程,一个线程接收数据一个线程发送数据

    在多线程环境下,一个线程专门负责接收数据,另一个线程负责发送数据,这样的设计可以避免阻塞。在TCP通信中,如果一个线程同时处理接收和发送,可能会遇到以下问题: 1. **阻塞**:如果线程正在接收数据,而此时...

    WEB服务器启动时加载一个ServerSocket服务

    ### WEB服务器启动时加载一个Java ServerSocket服务 在开发基于Java的Web应用过程中,有时我们需要在Web服务器启动的同时运行一个ServerSocket服务,以便监听特定端口并处理来自客户端的Socket连接请求。这样的需求...

    serverSocket

    当有客户端尝试连接时,`accept()`方法会被阻塞,直到一个连接建立。例如: ```java Socket clientSocket = serverSocket.accept(); ``` `accept()`方法返回一个新的`Socket`对象,代表与客户端的连接。 3. **...

    Java 实例 - ServerSocket 和 Socket 通信实例源代码+详细指导教程.zip

    `ServerSocket`提供了`accept()`方法,该方法会阻塞,直到有客户端连接为止,一旦连接建立,它会返回一个新的`Socket`对象,表示与客户端的连接。 二、`Socket`类 `Socket`是Java网络编程中的主要客户端接口,它...

    socket多线程通信源码

    在多线程环境下,每个连接到服务器的客户端都会创建一个独立的线程,这样可以避免因单线程处理所有请求而引起的阻塞问题。当服务器接收到新的客户端连接时,会创建一个新的线程来处理这个连接,同时保持对其他客户端...

    ServerSocket类.pdf

    - `ServerSocket(int port, int backlog, InetAddress bindAddr)`: 创建一个绑定到特定端口和IP地址的新`ServerSocket`,同时设置连接队列的长度。 ##### 3. 主要方法 - **accept()**: 这个方法会阻塞直到有客户端...

    serversocket socket web服务器

    当`ServerSocket`接收到新的连接请求时,它会在后台创建一个新的线程来处理这个连接,这样就可以同时处理多个客户端的请求,而不会阻塞其他请求的处理。这种设计模式在Web服务器中非常常见,被称为“并发连接”或...

    java-chatroom.rar_java ServerSocket

    - 由于ServerSocket的accept()方法是阻塞的,因此为了同时处理多个客户端的连接,服务器端通常会为每个连接创建一个新的线程。这样,即使服务器正在处理某个客户端的请求,也能接收其他客户端的连接。 7. **安全性...

    Socket+ServerSocket代码

    当有客户端尝试连接时,ServerSocket的accept()方法会被阻塞,直到一个连接建立为止。 接下来,我们讨论Socket类。Socket是Java.net包中的另一个重要类,它表示网络上的两个进程间通信的连接。在客户端,我们需要...

    Java Socket实例(服务器多线程)

    当一个客户端尝试连接到服务器时,服务器会创建一个新的线程来处理这个连接,这样就不会阻塞其他客户端的连接请求。这种模式被称为并发服务器,或称多线程服务器。 1. **Java Socket 基础**: - `Socket` 类:代表...

Global site tag (gtag.js) - Google Analytics