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()方法调用时并没有放弃对象的监视器。从输出中可以看到,一旦一个线程完成并释放锁,线程之间就不会发生交织,只有另一个线程进入同步块。