线程中的wait()和sleep()有什么区别?

我是否理解wait()-ing线程仍然处于运行模式并使用CPU周期,但sleep()-ing不消耗任何CPU周期正确?

为什么我们同时使用wait()和sleep()?

它们的实现在较低级别上有什么不同?


当前回答

从oracle文档页面的wait()方法的对象:

public final void wait()

导致当前线程等待,直到另一个线程调用该对象的notify()方法或notifyAll()方法。换句话说,这个方法的行为就像简单地执行调用wait(0)一样。 当前线程必须拥有该对象的监视器。线程释放该监视器的所有权并等待,直到另一个线程通知等待该对象监视器的线程被唤醒 可能会出现中断和虚假唤醒 此方法只能由该对象的监视器的所有者的线程调用

这个方法抛出

IllegalMonitorStateException -如果当前线程不是对象的监视器的所有者。 InterruptedException——如果任何线程在当前线程等待通知之前或期间中断了当前线程。抛出此异常时,当前线程的中断状态将被清除。

从oracle文档页关于Thread类的sleep()方法:

public static void sleep(long millis)

使当前正在执行的线程休眠(暂时停止执行)指定的毫秒数,这取决于系统计时器和调度器的精度和准确性。 线程不会失去任何监视器的所有权。

这个方法抛出:

IllegalArgumentException -如果millis的值为负 InterruptedException -如果任何线程中断了当前线程。抛出此异常时,当前线程的中断状态将被清除。

其他关键区别:

Wait()是一个非静态方法(实例方法),不同于静态方法sleep()(类方法)。

其他回答

一个尚未提及的关键区别是:

sleep()不会释放它在线程上持有的锁, 同步(锁){ thread . sleep (1000);// LOCK被持有 } Wait()释放它在对象上持有的锁。 同步(锁){ LOCK.wait ();// LOCK不被持有 }

这些方法用于不同的事情。

Thread.sleep(5000);   // Wait until the time has passed.

Object.wait();        // Wait until some other thread tells me to wake up.

Thread.sleep(n)可以被中断,但是Object.wait()必须被通知。 可以指定等待的最大时间:Object.wait(5000),这样就可以使用wait,呃,睡眠,但这样你就不得不使用锁了。

这两种方法都不会在休眠/等待时使用cpu。

这些方法是使用本地代码实现的,使用类似的结构,但方式不同。

自己寻找:本机方法的源代码是否可用?文件/src/share/vm/prims/jvm.cpp是起点…

等待会释放锁,而睡眠不会。处于等待状态的线程可以在调用notify或notifyAll时被唤醒。但是在睡眠的情况下,线程保持锁,并且只有在睡眠时间结束时才有资格。

简单地说,wait是等待,直到其他线程调用你,而sleep是在指定的一段时间内“不执行下一个语句”。

此外,sleep是Thread类中的静态方法,它在线程上操作,而wait()是Object类中的静态方法,在对象上调用。

还有一点,当你在某个对象上调用wait时,线程同步该对象,然后等待。:)

关于睡眠不释放锁,等待释放锁的例子

这里有两个类:

Main:包含Main方法和两个线程。 单例:这是一个单例类,有两个静态方法getInstance()和getInstance(boolean isWait)。 公共类Main { private static singletonA = null; private static Singleton singletonB = null; public static void main(String[] args)抛出InterruptedException { 线程threadA =新线程(){ @Override 公共无效运行(){ singletonA = Singleton.getInstance(true); } }; 线程threadB = new Thread() { @Override 公共无效运行(){ singletonB = Singleton.getInstance(); while (singletonA == null) { system . out。println("SingletonA still null"); } if (singletonA == singletonB) { system . out。println("两个单例是相同的"); }其他{ system . out。println("两个单例不相同"); } } }; threadA.start (); threadB.start (); } }

and

public class Singleton {

    private static Singleton _instance;

    public static Singleton getInstance() {

    if (_instance == null) {
        synchronized (Singleton.class) {
            if (_instance == null)
                _instance = new Singleton();
        }
    }
    return _instance;

}

public static Singleton getInstance(boolean isWait) {

    if (_instance == null) {
        synchronized (Singleton.class) {
            if (_instance == null) {
                if (isWait) {
                    try {
                        // Singleton.class.wait(500);//Using wait
                        Thread.sleep(500);// Using Sleep
                        System.out.println("_instance :"
                                + String.valueOf(_instance));
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }

                _instance = new Singleton();
            }
        }
    }
    return _instance;

 }
}

现在运行这个例子,你会得到以下输出:

_instance :null
Both singleton are same

这里由线程a和线程b创建的单例实例是相同的。这意味着线程b在外面等待,直到线程a释放它的锁。

现在通过注释Thread.sleep(500)来更改Singleton.java;Singleton.class.wait(500);. 这里因为Singleton.class.wait(500);方法threadA将释放所有获取锁并进入“Non Runnable”状态,threadB将获得change进入synchronized块。

现在再运行一次:

SingletonA still null
SingletonA still null
SingletonA still null
_instance :com.omt.sleepwait.Singleton@10c042ab
SingletonA still null
SingletonA still null
SingletonA still null
Both singleton are not same

这里由线程a和线程b创建的单例实例是不一样的,因为线程b得到了进入同步块的变化,500毫秒后,线程a从它的最后一个位置开始,并创建了一个新的单例对象。