• Java -- sleep and wait


     1、二者的来源

      sleep(),是Thread下面的静态方法/静态本地方法。

      wait(),是Object()的final方法。

     2、源码分析

      a、sleep()

     1  public static void sleep(long millis, int nanos)
     2     throws InterruptedException {
     3         if (millis < 0) {
     4             throw new IllegalArgumentException("timeout value is negative");
     5         }
     6 
     7         if (nanos < 0 || nanos > 999999) {
     8             throw new IllegalArgumentException(
     9                                 "nanosecond timeout value out of range");
    10         }
    12 if (nanos >= 500000 || (nanos != 0 && millis == 0)) { 13 millis++; 14 } 15 16 sleep(millis); 17 }

        当调用sleep(millis,nanos)的时候,内部调用的sleep(mills),如下:

    public static native void sleep(long millis) throws InterruptedException;

      这是一个静态的本地方法

      由一句话比较重要::: The thread does not lose ownership of any monitors.调用该方法的线程不会失去任何的监控。 不会失去该线程原来拥有的所有锁。

      实例:

      一个实体类User

     1 public class User {
     2     private int age;
     3 
     4     public int getAge() {
     5         return age;
     6     }
     7 
     8     @Override
     9     public String toString() {
    10         return "User [age=" + age + "]";
    11     }
    12 
    13     public void setAge(int age) {
    14         this.age = age;
    15     }
    16 
    17 }

      对该实体类的操作

     1 public class Main {
     2 
     3     public static void main(String[] args) {
     4 
     5         final User user = new User();
     6         user.setAge(10);
     7 
     8         synchronized (user) {
     9             try {
    10                 System.out.println("当前线程  <---->"
    11                         + Thread.currentThread().getName() + "<-----> 准备休眠");
    12 
    13                 Thread.sleep(10000);// 当前线程休眠
    14 
    15                 System.out.println("当前线程  <---->"
    16                         + Thread.currentThread().getName() + "<----->  完成休眠");
    17 
    18                 // 创建新的线程,对当前持锁对象执行相关操作
    19                 new Thread("new thread") {
    20                     public void run() {
    21                         System.out.println("当前线程  --->"
    22                                 + Thread.currentThread().getName());
    23                         System.out.println(user.getAge());
    24                     };
    25                 }.start();
    26 
    27             } catch (InterruptedException e) {
    28                 // TODO Auto-generated catch block
    29                 e.printStackTrace();
    30             }
    31         }
    32     }
    33 }

      执行结果:

    当前线程  <---->main<-----> 准备休眠
    当前线程  <---->main<----->  完成休眠
    当前线程  ---> new thread
    10
    

      所以当在一个synchronized方法中调用sleep()时,线程虽然休眠了,但是对象的机锁没有被释放,其他线程仍然无法访问这个对象。而wait()方法则会在线程休眠的同时释放掉机锁,其他线程可以访问该对象。所以只有在synchronized 块结束的时候,线程才会释放相应的锁。

      b、wait()

    The current thread must own this object's monitor. The thread releases ownership of this monitor and waits 
    until another thread notifies threads waiting on this object's monitor to wake up

      调用该方法的线程必须要拥有对象的控制权。调用之后,就会释放控制权,直到被其他的线程唤醒(notify() | notifyAll()) 。

    The thread then waits until it can re-obtain ownership of the monitor and resumes execution.
    

       之后,被唤醒的线程就继续等待,直到 重新获取对象的控制权。

    1   public final void wait() throws InterruptedException {
    2         wait(0);
    3     }

      调用wait(0)方法--final native

      public final native void wait(long timeout) throws InterruptedException;

      The specified amount of real time has elapsed, more or less.  If timeout is zero, however, then real time is not taken into consideration and the thread simply waits until notified.Then removed from the wait set for this object and re-enabled for thread scheduling. 到达wait时间或者被唤醒(还有一种被唤醒的方式--spurious wakeup,详细可以查看相关API),就会从线程的wait set中移除,等待重新被调度。

        

                          欢迎拍砖

  • 相关阅读:
    Eclipse 配置黑色主题
    [转发] win8安装mindget mindmanger
    2013.9小记
    【转发】Eclipse报错:Referenced classpath provider does not exist
    NoSql数据库初探-mongoDB读操作
    配置mongoDB服务
    NoSql数据库初探-mongoDB环境搭建
    pdf2htmlEx安装及测试
    关于ubuntu16无线网卡RTL8723BE频繁掉线及信号不足的解决办法
    一个简单的消息提示jquery插件
  • 原文地址:https://www.cnblogs.com/plxx/p/4655619.html
Copyright © 2020-2023  润新知