当前位置: 首页 > news >正文

网站服务器及运营维护公告高端品牌网站建设案例

网站服务器及运营维护公告,高端品牌网站建设案例,中学网站建设书,企业宣传片策划制作版本信息#xff1a; jdk版本#xff1a;jdk8u40 写在前面#xff1a; 大部分的Java程序员知道让线程睡眠的方法是Thread.sleep方法#xff0c;而这个方法是一个native方法#xff0c;让很多想知道底层如何让线程睡眠的程序员望而却步。所以笔者特意写在这篇文章#xf… 版本信息 jdk版本jdk8u40 写在前面 大部分的Java程序员知道让线程睡眠的方法是Thread.sleep方法而这个方法是一个native方法让很多想知道底层如何让线程睡眠的程序员望而却步。所以笔者特意写在这篇文章带各位读者剖析一下Thread.sleep方法背后的神秘。 源码剖析 话不多说先从Java层面看一下sleep这个方法。 public static native void sleep(long millis) throws InterruptedException;public static void sleep(long millis, int nanos) throws InterruptedException {// 非法逻辑if (millis 0) {throw new IllegalArgumentException(timeout value is negative);}// 非法逻辑if (nanos 0 || nanos 999999) {throw new IllegalArgumentException(nanosecond timeout value out of range);}// 如果大于500000就算一毫秒如果没有设置毫秒那么纳秒单位就四舍五入算一毫秒。if (nanos 500000 || (nanos ! 0 millis 0)) {millis;}// 调用重载的sleep方法。sleep(millis); } 这是一个重载的方法可以单独传入毫秒也可以传入毫秒和纳秒。不管调用哪一个sleep最终都是调用native的sleep方法所以接下来需要看底层如何对其实现。 src/share/native/java/lang/Thread.c 文件中有定义sleep的native实现方法。 static JNINativeMethod methods[] {{start0, ()V, (void *)JVM_StartThread},{stop0, ( OBJ )V, (void *)JVM_StopThread},{isAlive, ()Z, (void *)JVM_IsThreadAlive},{suspend0, ()V, (void *)JVM_SuspendThread},{resume0, ()V, (void *)JVM_ResumeThread},{setPriority0, (I)V, (void *)JVM_SetThreadPriority},{yield, ()V, (void *)JVM_Yield},{sleep, (J)V, (void *)JVM_Sleep},{currentThread, () THD, (void *)JVM_CurrentThread},{countStackFrames, ()I, (void *)JVM_CountStackFrames},{interrupt0, ()V, (void *)JVM_Interrupt},{isInterrupted, (Z)Z, (void *)JVM_IsInterrupted},{holdsLock, ( OBJ )Z, (void *)JVM_HoldsLock},{getThreads, ()[ THD, (void *)JVM_GetAllThreads},{dumpThreads, ([ THD )[[ STE, (void *)JVM_DumpThreads},{setNativeName, ( STR )V, (void *)JVM_SetNativeThreadName}, }; 这里是一个Thread类中所有native方法的映射表我们看到sleep映射为JVM_Sleep方法。 所以看到 src/share/vm/prims/jvm.cpp 文件中 JVM_Sleep方法 JVM_ENTRY(void, JVM_Sleep(JNIEnv* env, jclass threadClass, jlong millis))JVMWrapper(JVM_Sleep);// 改变状态为sleeping中。JavaThreadSleepState jtss(thread);EventThreadSleep event;if (millis 0) { // 如果传入的毫秒为0那么底层为转换为yield方法而yield仅仅是让出CPU的使用权让当前线程重新等待被调度if (ConvertSleepToYield) {os::yield();} else {// 如果不支持转换为yield方法那么会给出一个默认的睡眠时间。ThreadState old_state thread-osthread()-get_state();thread-osthread()-set_state(SLEEPING);os::sleep(thread, MinSleepInterval, false);thread-osthread()-set_state(old_state);}} else {// 拿到线程在sleep之前的状态。ThreadState old_state thread-osthread()-get_state();// 把线程状态改变成SLEEPINGthread-osthread()-set_state(SLEEPING);// 因为对于线程的操作只能交给操作系统if (os::sleep(thread, millis, true) OS_INTRPT) {// 如果睡眠期间被中断那么抛出中断异常。THROW_MSG(vmSymbols::java_lang_InterruptedException(), sleep interrupted);}// 改回之前的状态。thread-osthread()-set_state(old_state);} JVM_END 对这里做一个简单的总结 改变状态为Sleeping如果开发者传入的毫秒为0这里会根据策略转换成yield如果不支持转换就会给出默认的睡眠时间因为对于线程的操作只能交给操作系统完成所以这里调用os::sleep方法接下来会重点分析此方法。如果睡眠过程中被中断了那么会抛出中断异常睡眠正常完成后会把状态改变成之前的状态。 因为我们只关心Linux操作系统所以看到src/os/linux/vm/os_linux.cpp 文件中sleep方法。 int os::sleep(Thread* thread, jlong millis, bool interruptible) {ParkEvent * const slp thread-_SleepEvent ;slp-reset() ;OrderAccess::fence() ;// 判断是否响应中断。if (interruptible) {// 拿到进入之前的时间纳米为单位jlong prevtime javaTimeNanos();for (;;) {// 如果被中断了。if (os::is_interrupted(thread, true)) {return OS_INTRPT;}// 拿到最新的时间纳米为单位jlong newtime javaTimeNanos();if (newtime - prevtime 0) {// 最新的时间小于之前的时间这不是扯淡么。assert(!Linux::supports_monotonic_clock(), time moving backwards);} else {// 一秒 1000毫秒// 一秒 1000000000纳秒// NANOSECS_PER_MILLISEC 1000000// 这里是获取到当前睡眠的时间并且从纳秒转换成毫秒。millis - (newtime - prevtime) / NANOSECS_PER_MILLISEC;}// 时间到了直接退出。if(millis 0) {return OS_OK;}prevtime newtime;{JavaThread *jt (JavaThread *) thread;ThreadBlockInVM tbivm(jt);// 改变线程状态。OSThreadWaitState osts(jt-osthread(), false /* not Object.wait() */);jt-set_suspend_equivalent();// 睡眠slp-park(millis);}}} else {OSThreadWaitState osts(thread-osthread(), false /* not Object.wait() */);jlong prevtime javaTimeNanos();for (;;) {jlong newtime javaTimeNanos();if (newtime - prevtime 0) {assert(!Linux::supports_monotonic_clock(), time moving backwards);} else {millis - (newtime - prevtime) / NANOSECS_PER_MILLISEC;}if(millis 0) break ;prevtime newtime;slp-park(millis);}return OS_OK ;} } 对这里做一个简单的总结 拿到当前线程对应的parkEvent这个可以理解为提供了底层睡眠和阻塞的API。判断是否可以响应中断如果响应中断那么每次循环都会判断是否被中断了获取当前时间此时间是纳秒纳秒转换成毫秒因为底层睡眠时间需要时毫秒单位这里为什么获取当前时间不直接拿毫秒因为考虑到精准度的问题调用parkEvent的park方法进入操作系统睡眠。 考虑到文章的篇幅问题parkEvent的park方法就不细追了。大家可以黑盒的理解它就是让当前线程去阻塞而传入的单位就是阻塞的时间。 总结 sleep的底层实现并不复杂但是不看源码是不会知道如果传入的时间为0会优化成yield方法并且在底层并不会像Object类中wait方法一样释放锁资源等等
http://www.zqtcl.cn/news/449699/

相关文章:

  • 网站解决访问量超载做国外营销型网站设计
  • 思科中国网站开发案例网站如何进行建设
  • 网页设计与网站建设郑州大学怎么在传奇网站上做宣传
  • 中国建设银行重庆网站首页sns网站需求
  • 外网常用网站全网网站建设设计
  • 成都建设网站费用做数据库与网站招什么人
  • 最好的wordpress教程啥叫优化
  • 哪个网站做网销更好网站流量流出异常
  • 广州网站定做纸箱手工制作大全
  • 数据库修改网站后台密码cms三合一网站源码
  • 一般做哪些外贸网站丰南建设局网站
  • 网站如何被收录情况自己做的网站如何实现下载文件
  • 龙岩网站设计一般要多久深圳做自适应网站设计
  • 类似于拼多多的网站怎么做资料下载网站建设
  • 做商城网站哪里网站官网建设的价格
  • 网站怎么做用户体验山东富国建设投资有限公司网站
  • app ui模板网站首页改版影响优化
  • 周村网站制作哪家好网站设计基本要素
  • 网站制作与维护费用wordpress文章页不显示侧边
  • 嘉兴网站建设正规公司做室内设计人喜欢的网站
  • 入侵dedecms网站管理员密码百度注册域名免费建站
  • 找晚上做的工作去哪个网站企业开发软件公司拓展方案
  • 济宁建站公司wordpress博客入门
  • 做外贸需要网站wordpress app 打包
  • 免费网站站长查询丽水微信网站建设公司
  • 广州品牌网站建设先做网站 先备案
  • jsp系统网站建设带源代码梧州网页设计
  • 二手书籍交易网站开发方式关键词seo排名优化如何
  • 陕西西安潍坊网站seo外包
  • 计算机专业网站开发开题报告网站推广营销怎么做