Java中sleep()和wait()方法之间的区别

时间:2020-01-09 10:35:08  来源:igfitidea点击:

在本文中,我们将看到Java中sleep()和wait()方法之间的区别。由于这两个方法sleep()和wait()都导致当前正在执行的线程挂起其执行,因此某些用户发现它难以区分sleep和wait方法。因此,让我们尝试看看Java中sleep()和wait()方法之间的区别。

Java中的sleep()与wait()

这两种方法之间的主要区别在于,wait方法用于线程间通信,并且与notify()和notifyAll()方法协同工作,并且只能在同步上下文中使用。在任何上下文中都可以使用as sleep()方法。

  • sleep()方法是Thread类中定义的静态方法,调用Thread.sleep()方法会使当前正在执行的线程在指定时间内暂停执行。在对象类中定义了wait()方法,它是一个实例方法(在类的对象上调用)。
  • sleep()方法适用于当前线程。由于wait()方法在Object类中定义并在对象上调用,因此它用于线程间通信。在同一对象上调用notify()或者notifyAll()方法时,它将导致当前正在等待同一对象的线程唤醒。
  • sleep()方法可以从任何上下文中调用。不必强制在同步方法或者块中调用它。当调用wait()方法时,它导致当前线程释放其持有的对象的锁。由于线程在进入同步方法或者块时会获取对象的锁,因此只能在同步上下文中使用wait()方法。如果从未同步的方法(或者块)中调用wait()方法,则将在运行时引发IllegalMonitorStateException。请参阅为什么必须从同步方法或者块中调用为什么wait(),notify()和notifyAll()方法,以了解为什么必须从同步上下文中调用wait,notify和notifyAll方法的原因。
  • 如果在同步上下文中使用sleep()方法调用当前线程,则不必释放其持有的锁。当前线程必须释放锁,并在调用wait()方法时进入等待状态,这使另一个线程有机会获得锁并输入同步方法或者块。
  • 在指定的时间(如sleep方法中给定的时间)过去或者线程被中断之后,通过调用sleep()方法暂停的线程将唤醒。在同一对象上调用notify或者notifyAll()方法时,由于调用wait()方法而处于等待状态的线程退出等待状态。 wait()方法wait(long timeout)和wait(long timeout,int nanos)有两种变体,其中可以指定等待时间。如果使用了这些wait()方法中的任何一种,则在通知线程或者经过给定的实时量后,线程将被唤醒。等待线程也可以被中断。

Java Sleep方法示例

public class InterruptDemo implements Runnable {
  @Override
  public void run() {
    synchronized(this){
      for(int i = 0; i < 5; i++){
        System.out.println(Thread.currentThread().getName() + " Value - " + i);
        try {
          Thread.sleep(500);
        } catch (InterruptedException e) {
          System.out.println("Thread " + Thread.currentThread().getName() 
                      + " interrupted, reason " + e.getMessage());
          throw new RuntimeException("Thread interrupted", e);
        }
      }
    }
  }
  public static void main(String[] args) {
    InterruptDemo id = new InterruptDemo();
    Thread t1 = new Thread(id);
    Thread t2 = new Thread(id);
    //long startTime = System.currentTimeMillis();
    t1.start();
    t2.start();
  }
}

输出:

Thread-0 Value - 0
Thread-0 Value - 1
Thread-0 Value - 2
Thread-1 Value - 0
Thread-1 Value - 1
Thread-1 Value – 2

如我们所见,在同步上下文线程中使用sleep()方法调用时并没有放弃对象的监视器。从输出中可以看到,一旦一个线程完成并释放锁,线程之间就不会发生交织,只有另一个线程进入同步块。