文档章节

关于如何让线程主动让出CPU和如何让线程主动放弃锁

Hosee
 Hosee
发布于 2016/05/12 11:24
字数 685
阅读 1754
收藏 5

刚刚突然想到

如何让线程主动让出CPU?

如何让线程主动放弃持有的锁?

想了下,有点模糊,记录一下方便回忆。

如何让线程主动让出CPU

Thread.sleep();

sleep就是正在执行的线程主动让出cpu,cpu去执行其他线程,在sleep指定的时间过后,cpu才会回到这个线程上继续往下执行,如果当前线程进入了同步锁,sleep方法并不会释放锁,即使当前线程使用sleep方法让出了cpu,但其他被同步锁挡住了的线程也无法得到执行。

在多线程争用的情况,拥有锁的线程进行一些耗时操作,会极大降低吞吐量(amdahl定律),如果在同步块中使用sleep就是一种糟糕的做法,它不会释放锁却阻止其他线程获得锁。

Thread.yield();

yeild是个native静态方法,这个方法是想把自己占有的cpu时间释放掉,然后和其他线程一起竞争(注意yeild的线程还是有可能争夺到cpu,注意与sleep区别)。在javadoc中也说明了,yeild是个基本不会用到的方法,一般在debug和test中使用。

Object.wait();

wait会把当前的锁释放掉同时阻塞住,让出CPU;当别的线程调用该 Object 的 notify/notifyAll 之后,有可能得到 CPU,同时重新获得锁。

当然同样的

condition.await();

也会释放锁并且让出CPU;

当然很多竞争锁失败的线程最终也会阻塞住,但是这不是主动让出CPU,不在讨论范围内。

Thread.stop();

太过暴力,不推荐使用,同时会释放所有锁。容易导致数据不一致,具体请查看[高并发Java 二] 多线程基础

Thread.currentThread().suspend();

挂起线程,suspend不会释放锁,suspend容易发生死锁,不推荐使用。原因请查看[高并发Java 二] 多线程基础

LockSupport.park();

与suspend一样挂起线程,但是park/unpark不会发生死锁,原因请查看[高并发Java 五] JDK并发包1

Java中Thread的状态有:

NEW

RUNNABLE

WAITING:Object.wait(),LockSupport.park()

TIMED_WAITING:Thread.sleep(long),Object.wait(long),LockSupport.parkNanos(long)

BLOCKED:Object.wait()

TERMINATED:Thread.stop()

如何让线程主动放弃持有的锁

Object.wait();
condition.await();
Thread.stop();

上面已经说了

当然所有释放锁的操作都可以:

reentrantLock.unlock();
semaphore.release();

要注意的是以下操作不会释放锁,在上面已经谈到了,这里再列举以下:

Thread.sleep();
Thread.yield();
Thread.currentThread().suspend();
LockSupport.park();

Reference:

1. http://www.lai18.com/content/2571817.html

2. https://www.zhihu.com/question/23328075

© 著作权归作者所有

共有 人打赏支持
Hosee
粉丝 563
博文 135
码字总数 209956
作品 0
杭州
程序员
私信 提问
C++ yield()与sleep_for()

C++11 标准库提供了yield()和sleep_for()两个方法。 (1)std::this_thread::yield(): 线程调用该方法时,主动让出CPU,并且不参与CPU的本次调度,从而让其他线程有机会运行。在后续的调度周...

yepanl
2018/09/19
0
0
Java中sleep()与wait()区别

学习时正好碰到这两个方法,就查阅相关资料,并通过程序实现,进行区别一下: 1、每个对象都有一个锁来控制同步访问,Synchronized关键字可以和对象的锁交互,来实现同步方法或同步块。sleep...

Airship
01/09
0
0
java多线程之:线程对象一些api

一:wait()方法,wait(long timeout) --->锁对象调用wait()方法,让当前线程小a进入等待状态,阻塞住,并让出当先线程拥有的锁。 --->直到其他线程用锁对象调用notifyAll(),notify()将小a从w...

无信不立
2016/08/18
0
0
大并发下的高性能编程 – 改进的(用户态)自旋锁

前言 多线程程序中,锁的使用往往成为系统性能的关键。在做地址可视化项目的时候,由于内存管理部分需要频繁的更新内存的引用计数,所以产生了使用自旋锁的想法,这篇文章我们从自旋锁的性能...

微wx笑
2015/01/30
0
0
JAVA线程sleep和wait方法区别

昨天面试,突然被问到sleep 和 wait的区别,一下子有点蒙,在这里记一下,以示警戒。 首先说sleep,sleep就是正在执行的线程主动让出cpu,cpu去执行其他线程,在sleep指定的时间过去后,cpu...

徐玉强
2018/06/25
0
0

没有更多内容

加载失败,请刷新页面

加载更多

发布xxl-job executor dotnet core 执行器的实现

DotXxlJob [github][https://github.com/xuanye/DotXxlJob] xxl-job的dotnet core 执行器实现,支持XXL-JOB 2.0+ 1 XXL-JOB概述 [XXL-JOB][1]是一个轻量级分布式任务调度平台,其核心设计目标...

假正经哥哥
今天
2
0
mysql 查询当天、本周,本月,上一个月的数据

今天 select * from 表名 where to_days(时间字段名) = to_days(now()); 昨天 SELECT * FROM 表名 WHERE TO_DAYS( NOW( ) ) - TO_DAYS( 时间字段名) <= 1 近7天 SELECT * FROM 表名 wher......

BraveLN
今天
3
0
Spring 事务初始化源码分析

相关文章 Spring 事务使用详解 Spring AOP 创建代理的源码解析 Spring AOP 注解方式源码解析 Spring AOP 功能使用详解 Spring 的 getBean 方法源码解析 Spring bean 创建过程源码解析 Spring...

TSMYK
今天
1
0
Android Multimedia框架总结(六)C++中MediaPlayer的C/S架构

前面几节中,都是通过java层调用到jni中,jni向下到c++层并未介绍 看下Java层一个方法在c++层 MediaPlayer后续过程 frameworks/av/media/libmedia/MediaPlayer.cpp 找一个我们之前熟悉的setDa...

天王盖地虎626
今天
3
0
【Linux】【MySQL】CentOS7安装最新版MySQL8.0.13(最新版MySQL从安装到运行)

1、前言   框框博客在线报时:2018-11-07 19:31:06   当前MySQL最新版本:8.0.13 (听说比5.7快2倍)   官方之前表示:MySQL 8.0 正式版 8.0.11 已发布,MySQL 8 要比 MySQL 5.7 快 2 ...

Code辉
今天
5
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部