在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`的`close()`方法是一个关键操作,它的主要作用是让服务器释放占用的端口,并终止与所有已建立连接的客户端的连接。执行`close()`方法后,任何尝试连接到此`ServerSocket`的客户端请求都将被拒绝...
在这个场景中,服务器端通过一个线程处理一个客户端的请求,当请求被处理时,该线程会处于阻塞状态,直到客户端发送的数据被完全接收并响应。这种方式虽然简单,但可能无法有效应对大量并发连接。 首先,我们来看`...
同时,为了处理多个并发连接,我们通常会为每个连接创建一个新的线程,这样就可以在不中断其他连接的情况下服务新的客户端。 接下来是`SocketUtils.java`。这个文件可能包含了通用的Socket操作工具方法,例如创建...
Java多线程环境下使用ServerSocket和Socket进行服务端与客户端之间的通信是一个经典的网络编程模型。在这个模型中,服务端使用ServerSocket类监听特定端口,等待客户端的连接请求。而客户端则通过Socket类建立与...
`ServerSocket`是Java中的服务器端套接字类,它允许服务器创建一个监听特定端口的套接字,等待客户端的连接请求。`ServerSocket`的基本用法如下: ```java import java.net.ServerSocket; import java.io....
以下是一个简单的单线程`ServerSocket`示例: ```java import java.net.ServerSocket; import java.net.Socket; public class SingleThreadServer { public static void main(String[] args) throws Exception { ...
一旦有连接请求到来,`ServerSocket`就会创建一个新的`ClientSocket`对象来处理这个连接,允许服务器与客户端进行数据交换。 `ClientSocket`则是客户端的网络组件,用于建立到远程服务器的连接。开发者可以通过设置...
在聊天室系统中,每个连接的客户端都会创建一个新的线程,以便服务器可以同时处理来自不同客户端的请求,避免了单线程模型下的阻塞问题。例如,当一个客户端发送消息时,其他客户端可以同时接收和发送信息,保持系统...
创建一个ServerSocket实例时,你需要指定一个端口号。一旦创建,ServerSocket就会阻塞,直到有客户端尝试连接到该端口。例如: ```java ServerSocket serverSocket = new ServerSocket(8080); ``` 当一个连接请求...
在多线程环境下,一个线程专门负责接收数据,另一个线程负责发送数据,这样的设计可以避免阻塞。在TCP通信中,如果一个线程同时处理接收和发送,可能会遇到以下问题: 1. **阻塞**:如果线程正在接收数据,而此时...
### WEB服务器启动时加载一个Java ServerSocket服务 在开发基于Java的Web应用过程中,有时我们需要在Web服务器启动的同时运行一个ServerSocket服务,以便监听特定端口并处理来自客户端的Socket连接请求。这样的需求...
当有客户端尝试连接时,`accept()`方法会被阻塞,直到一个连接建立。例如: ```java Socket clientSocket = serverSocket.accept(); ``` `accept()`方法返回一个新的`Socket`对象,代表与客户端的连接。 3. **...
`ServerSocket`提供了`accept()`方法,该方法会阻塞,直到有客户端连接为止,一旦连接建立,它会返回一个新的`Socket`对象,表示与客户端的连接。 二、`Socket`类 `Socket`是Java网络编程中的主要客户端接口,它...
在多线程环境下,每个连接到服务器的客户端都会创建一个独立的线程,这样可以避免因单线程处理所有请求而引起的阻塞问题。当服务器接收到新的客户端连接时,会创建一个新的线程来处理这个连接,同时保持对其他客户端...
- `ServerSocket(int port, int backlog, InetAddress bindAddr)`: 创建一个绑定到特定端口和IP地址的新`ServerSocket`,同时设置连接队列的长度。 ##### 3. 主要方法 - **accept()**: 这个方法会阻塞直到有客户端...
当`ServerSocket`接收到新的连接请求时,它会在后台创建一个新的线程来处理这个连接,这样就可以同时处理多个客户端的请求,而不会阻塞其他请求的处理。这种设计模式在Web服务器中非常常见,被称为“并发连接”或...
- 由于ServerSocket的accept()方法是阻塞的,因此为了同时处理多个客户端的连接,服务器端通常会为每个连接创建一个新的线程。这样,即使服务器正在处理某个客户端的请求,也能接收其他客户端的连接。 7. **安全性...
当有客户端尝试连接时,ServerSocket的accept()方法会被阻塞,直到一个连接建立为止。 接下来,我们讨论Socket类。Socket是Java.net包中的另一个重要类,它表示网络上的两个进程间通信的连接。在客户端,我们需要...
当一个客户端尝试连接到服务器时,服务器会创建一个新的线程来处理这个连接,这样就不会阻塞其他客户端的连接请求。这种模式被称为并发服务器,或称多线程服务器。 1. **Java Socket 基础**: - `Socket` 类:代表...