为什么线程唤醒和阻塞的代价大?

Java的线程是映射到操作系统原生线程之上的,如果要阻塞或唤醒一个线程就需要操作系统介入,需要在用户态和核心态之间切换,这种切换会消耗大量的系统资源,因为用户态与内存态都有各自专用的内存空间,专用的寄存器等,用户态切换至内核态需要传递给许多变量、参数给内核,内核也需要保护好用户态在切换时的一些寄存器值,变量等,以便内核态调用结束后切换会用户态继续工作。
1.如果高频进行线程的切换操作,将消耗许多CPU的处理时间
2.如果对那些需要同步的简单的代码块,获取锁挂起操作消耗的时间比用户代码执行的时间还要长,这种同步策略显然是糟糕的。
synchronized会导致争不到锁的线程进入阻塞状态,所以它是重量级锁。

Java中,当一个线程处于阻塞状态(通常是通过调用某个同步块、`wait()`方法或者I/O操作导致的),其他线程通常无法直接唤醒这个阻塞线程唤醒一个阻塞线程通常涉及到以下几个步骤: 1. **发送中断信号**:你可以调用`thread.interrupt()`方法中断线程,这会设置一个中断标志。对于`Object.wait()`方法,可以使用`notify()`或`notifyAll()`方法来唤醒一个或所有等待该对象的对象。 ```java // 示例 Thread thread = ...; if (thread.isInterrupted()) { thread.currentThread().interrupt(); // 如果线程已中断则再次中断 } ``` 2. **检查中断标志**:线程需要在其循环或阻塞操作内部检查中断标记,如果发现中断,通常会立即退出循环或者处理中断逻辑。 ```java while (!thread.isInterrupted() && someCondition) { try { // 阻塞操作 synchronized (object) { object.wait(); } } catch (InterruptedException e) { // 检查并清除中断标志 e.printStackTrace(); thread.interrupted(); } } ``` 3. **清理资源**:在适当的候,线程应该关闭任何打开的流、数据库连接等,并释放相关的同步资源。 记住,`interrupt()`方法只是设定了一个标志,实际唤醒还需要线程自行检查。如果你期待线程立即结束,可能需要考虑使用`ThreadDeath`类或者`Thread.stop()`方法(已弃用,尽量避免)。但在现代最佳实践中,我们通常鼓励使用中断机制而不是强制终止。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值