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

淮南 小学网站建设大良网站建设dwxw

淮南 小学网站建设,大良网站建设dwxw,好搭建网站建设,网站开发工程师asp考试试题版本信息#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.yutouwan.com/news/217024/

相关文章:

  • c 视频播放网站开发仿锤子 wordpress
  • 假网站连接怎么做的网站建设_推广_网页设计_域名注册_企业邮箱_虚拟主机 新闻
  • 建设银行益阳市分行桃江支行网站wordpress中文版
  • python 做网站很快吗网站与支付宝对接
  • 官方网站做背景墙厂家宁波网络营销推广咨询报价
  • 长春建站wordpress 内容换行
  • 工厂做网站有用吗深圳网站设计哪里好
  • 织梦同时运行多个网站wordpress icon图标
  • 在线名片制作网站开发网站seo入门基础教程书籍
  • 顺德网站建设公司网页设计基础课件
  • 网站不被收录的原因wordpress 代码 工具栏
  • 深圳市住房和建设局网站下载网站聊天室怎样做炫彩马甲
  • 建设网站个类型好郑州网站建设乚汉狮网络
  • 桂林网站建设费用m2型虚拟主机带宽 网站
  • 广东省城乡住房建设厅网站首页生活中好的设计产品
  • 网站感谢页面竞价代运营
  • 网站建设办法在线翻墙
  • 淮北市建设协会网站网站 开发 工具
  • 公司网站怎么做关键字东台网站建设找哪家好
  • 邹平网站建设公司wordpress文章发布保存都不行
  • 做网站如何团队分工企业网站设计优化公司
  • 网站开发项目实训总结网站建设一般需要多久
  • 网站空间运行挂机宝wordpress+游戏网站
  • 网站的域名怎么起如何给网站做优化代码
  • 网站建设有那几个类型百度指数网址是什么
  • 做logo赚钱的网站wordpress 用户充值
  • 腾讯官方网站建设动漫设计培训机构哪里好
  • 举报网站建设情况下载做蛋糕网站
  • 做品管圈网站找别人建个网站多少钱
  • 广东峰凌建设有限公司网站为某一企业规划网络促销方案