线程的Interrupted

本文详细解析了Java中线程中断的实现机制,包括如何使用t.interrupt()方法标记线程中断状态,以及线程在遇到wait、join或sleep等方法时如何响应中断并抛出InterruptedException。

线程调用t.interrupt();其实就是给线程设置一个中断状态的标识,并不能让线程马上终止。
If this thread is blocked in an invocation of the wait(), wait(long), or wait(long, int) methods of the Object class, or of the join(), join(long), join(long, int), sleep(long), or sleep(long, int), methods of this class, then its interrupt status will be cleared and it will receive an InterruptedException.  。

如果线程调用了wait ,jion, sleep方法而阻塞->>t.interrupt() -->将会抛出一个InterruptedException,异常抛出后会把刚才设置的中断状态标识也清除掉。

public class InterruptDemo {

	public static void main(String[] args) {

		Thread ex = new ExThread();
		ex.start();
		try {
			Thread.sleep(2000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		ex.interrupt();

	}

}

class ExThread extends Thread {

	@Override
	public void run() {
		super.run();
		while (!Thread.currentThread().isInterrupted()) {
			System.out.println("ExThread 运行中:" + Thread.currentThread().isInterrupted());
			try {
				sleep(1000);
			} catch (InterruptedException e) {
				e.printStackTrace();
				System.out.println("InterruptedException异常:" + isInterrupted());//这里是false,因为异常抛出后,会清除中断状态的标识。所以While循环条件依旧满足,线程继续在那run..

			}

		}
	}

}
运行结果:

ExThread 运行中:false
ExThread 运行中:false
java.lang.InterruptedException: sleep interrupted
InterruptedException异常:false at java.lang.Thread.sleep(Native Method)
at com.thread.ExThread.run(InterruptDemo.java:28)
ExThread 运行中:false
ExThread 运行中:false
ExThread 运行中:false
ExThread 运行中:false
ExThread 运行中:false

如果我们在catch (InterruptedException e) 中再设置一下 this.interrupt();
public class InterruptDemo {

	public static void main(String[] args) {

		Thread ex = new ExThread();
		ex.start();
		try {
			Thread.sleep(2000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		ex.interrupt();

	}

}

class ExThread extends Thread {

	@Override
	public void run() {
		super.run();
		while (!Thread.currentThread().isInterrupted()) {
			System.out.println("ExThread 运行中:" + Thread.currentThread().isInterrupted());
			try {
				sleep(1000);
			} catch (InterruptedException e) {
				e.printStackTrace();
				System.out.println("InterruptedException异常:" + isInterrupted());
				this.interrupt();
				System.out.println("是否中断:" + this.isInterrupted());

			}

		}
	}

}



运行结果如下:

ExThread 运行中:falseExThread 运行中:falseInterruptedException异常:false是否中断:truejava.lang.InterruptedException: sleep interruptedat java.lang.Thread.sleep(Native Method)at com.thread.ExThread.run(InterruptDemo.java:28)

看吧,线程的whlie停止了。把上面的代码稍微改下:

public class InterruptDemo {

	public static void main(String[] args) {

		Thread ex = new ExThread();
		ex.start();
		try {
			Thread.sleep(2000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		ex.interrupt();

	}

}

class ExThread extends Thread {

	@Override
	public void run() {
		super.run();
		while (!Thread.currentThread().isInterrupted()) {
			System.out.println("ExThread 运行中:" + Thread.currentThread().isInterrupted());
			try {
				sleep(1000);
			} catch (InterruptedException e) {
				e.printStackTrace();
				System.out.println("InterruptedException异常:" + isInterrupted());
				this.interrupt();
<span style="color:#ff0000;">				System.out.println("是否中断:" + Thread.interrupted());
				System.out.println("isInterrupted:" + this.isInterrupted());</span>

			}

		}
	}

}


运行结果变成:

ExThread 运行中:false
ExThread 运行中:false
java.lang.InterruptedException: sleep interrupted
InterruptedException异常:false
是否中断:true
isInterrupted:false
ExThread 运行中:false
at java.lang.Thread.sleep(Native Method)
at com.thread.ExThread.run(InterruptDemo.java:28)
ExThread 运行中:false
ExThread 运行中:false
ExThread 运行中:false
ExThread 运行中:false
ExThread 运行中:false
ExThread 运行中:false
ExThread 运行中:false


为嘛呢? 因为Thread.interrupted()如果当前线程isAlive()不仅会返回当前线程的的中断状态值,并且会清除它,就是说返回true,后把它改为false.



在多线程处理场景下,Redis 出现 `command interrupted` 错误通常是由于连接中断、超时、资源竞争等原因导致的。以下是一些可能的解决办法: ### 检查网络连接 确保客户端与 Redis 服务器之间的网络连接稳定,没有丢包、延迟过高或网络中断的情况。可以通过 `ping` 命令测试网络连通性,也可以使用 `telnet` 命令检查 Redis 端口是否开放。 ```bash ping <redis_server_ip> telnet <redis_server_ip> <redis_port> ``` ### 增加超时时间 如果是因为命令执行时间过长导致超时,可以适当增加客户端的超时时间设置。不同的 Redis 客户端库设置超时时间的方式不同,以下是 Python 的 `redis-py` 库的示例: ```python import redis # 增加 socket_timeout 参数 r = redis.Redis(host='localhost', port=6379, db=0, socket_timeout=10) ``` ### 优化 Redis 命令 检查多线程中执行的 Redis 命令是否过于复杂或耗时过长。可以尝试将大的操作拆分成多个小的操作,或者使用 Redis 的管道(pipeline)来批量执行命令,减少网络开销和执行时间。 ```python import redis r = redis.Redis(host='localhost', port=6379, db=0) pipe = r.pipeline() pipe.set('key1', 'value1') pipe.set('key2', 'value2') results = pipe.execute() ``` ### 处理并发问题 多线程环境下可能会出现并发访问 Redis 的情况,导致资源竞争和命令中断。可以使用线程安全的 Redis 连接池来管理连接,确保每个线程使用独立的连接。以下是 Python 的 `redis-py` 库使用连接池的示例: ```python import redis # 创建连接池 pool = redis.ConnectionPool(host='localhost', port=6379, db=0) # 从连接池获取连接 r = redis.Redis(connection_pool=pool) ``` ### 检查 Redis 服务器负载 如果 Redis 服务器负载过高,可能会导致命令执行缓慢或中断。可以使用 Redis 的 `INFO` 命令查看服务器的状态和性能指标,根据情况进行优化,如增加服务器资源、调整 Redis 配置等。 ```bash redis-cli INFO ``` ### 重试机制 在代码中实现重试机制,当遇到 `command interrupted` 错误时,自动重试一定次数。以下是 Python 的示例代码: ```python import redis import time MAX_RETRIES = 3 RETRY_DELAY = 1 r = redis.Redis(host='localhost', port=6379, db=0) def execute_with_retry(command, *args, **kwargs): retries = 0 while retries < MAX_RETRIES: try: return getattr(r, command)(*args, **kwargs) except redis.exceptions.ConnectionError as e: print(f"Command interrupted: {e}. Retrying in {RETRY_DELAY} seconds...") retries += 1 time.sleep(RETRY_DELAY) raise Exception("Max retries exceeded.") # 使用重试机制执行命令 result = execute_with_retry('get', 'key') ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值