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

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

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

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


当前回答

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

这里有两个类:

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从它的最后一个位置开始,并创建了一个新的单例对象。

其他回答

wait()和sleep()的区别

最根本的区别是wait()是Object的非静态方法,sleep()是Thread的静态方法。 主要的区别是wait()释放锁,而sleep()在等待时不释放任何锁。 Wait()用于线程间通信,而sleep()通常用于在执行时引入暂停。 wait()应该从synchronise内部调用,否则我们会得到一个IllegalMonitorStateException,而sleep()可以在任何地方调用。 要从wait()再次启动线程,必须无限期地调用notify()或notifyAll()。至于sleep(),线程肯定会在指定的时间间隔后启动。

相似之处

两者都使当前线程进入不可运行状态。 两者都是本机方法。

应该从同步块调用:wait()方法总是从同步块调用,即wait()方法需要在调用它的对象之前锁定对象监视器。但是sleep()方法可以从外部同步块调用,即sleep()方法不需要任何对象监视器。

IllegalMonitorStateException:如果wait()方法被调用而没有获得对象锁,则IllegalMonitorStateException在运行时抛出,但sleep()方法从不抛出此类异常。

属于哪个类:wait()方法属于java.lang.Object类,sleep()方法属于java.lang.Thread类。

在对象或线程上调用:wait()方法在对象上调用,而sleep()方法在线程上调用,而不是在对象上。

线程状态:当在对象上调用wait()方法时,持有对象监视器的线程从运行状态变为等待状态,只有在该对象上调用notify()或notifyAll()方法时才能返回到可运行状态。然后线程调度程序将线程从可运行状态调度到运行状态。 当sleep()在线程上被调用时,它会从运行状态转到等待状态,并在休眠时间结束时返回到可运行状态。

从同步块调用时:当wait()方法被调用时,线程离开对象锁。但是sleep()方法在从同步块或方法线程调用时不会留下对象锁。

更多参考资料

让我们假设你正在听到歌曲。

只要当前歌曲正在运行,下一首歌就不会播放,即由下一首歌调用Sleep()

如果你完成了这首歌,它会停止,直到你选择播放按钮(notify())它才会播放,即由当前歌曲调用的wait()。

在这两种情况下,歌曲都进入等待状态。

方法wait(1000)使当前线程休眠一秒。 如果线程接收到notify()或notifyAll()方法调用,那么线程的睡眠时间可能小于1秒。 调用sleep(1000)会导致当前线程休眠1秒。 此外,睡眠线程不持有锁任何资源。但是等待线程可以。

在研究了wait和sleep之后,我总结了一些不同的关键注意事项,首先看一下使用wait()和sleep()的示例:

例1:使用wait()和sleep():

synchronized(HandObject) {
    while(isHandFree() == false) {
        /* Hand is still busy on happy coding or something else, please wait */
        HandObject.wait();
    }
}

/* Get lock ^^, It is my turn, take a cup beer now */
while (beerIsAvailable() == false) {
    /* Beer is still coming, not available, Hand still hold glass to get beer,
       don't release hand to perform other task */
    Thread.sleep(5000);
}

/* Enjoy my beer now ^^ */
drinkBeers();

/* I have drink enough, now hand can continue with other task: continue coding */
setHandFreeState(true);
synchronized(HandObject) {
    HandObject.notifyAll();
}

让我们明确一些关键的注意事项:

呼吁: wait():调用当前持有handdobject对象的线程 sleep():在线程上调用执行任务获取啤酒(是类方法,因此影响当前运行的线程) 同步: wait():当同步多线程访问同一对象(HandObject)时(当多个线程之间需要通信时(线程执行编码,线程执行获取啤酒)访问同一对象(HandObject) sleep():当等待状态继续执行时(等待啤酒可用) 持有锁: wait():释放锁,让其他对象有机会执行(HandObject是空闲的,你可以做其他工作) sleep():保持锁至少t次(或直到中断)(我的工作仍然没有完成,我继续持有锁,等待一些条件继续) 唤醒条件: wait():直到调用notify(), notifyAll()从对象 Sleep():直到至少超时或调用中断 最后一点是当estani表示:

通常使用sleep()进行时间同步,使用wait()进行时间同步 multi-thread-synchronization。

如果我说错了,请指正。