A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

java多线程 sleep()和wait()的区别 本人是初学者 希望解答者能给出详细的解答 能举出实例说明更好

评分

参与人数 1技术分 +1 收起 理由
Rancho_Gump + 1

查看全部评分

8 个回复

正序浏览
首先你要清楚多线程的生命周期:
初始状态——就绪状态——运行状态——阻塞状态——死亡状态
1、初始状态就是线程的创建,当线程创建完成后,该线程就处于初始状态
2、当线程调用start()方法后,线程就处于就绪状态,意思就是说随时可以进行运行
3、运行状态,当该线程获得CUP资源后,就进入了执行状态
4、当线程遇到sleep() wait()等方法时,线程不会再运行下去了,需要一个条件才能继续运行
5、当执行完run()方法后,就完成了整个线程,进入了死亡状态

sleep()和 wait();都是造成阻塞的原因
sleep(long millis):从字面上可以看得出,这是让这个线程休息多长时间,当线程休息够时间后,进入就绪状态,等待获得CPU的资源,来执行自己没有执行完的代码
wait():这个方法是我进入类休眠状态,也就是动物的冬眠,只用当春天到来后动物才会结束冬眠,而wait是需要使用notify来把他唤醒,来结束休眠。
回复 使用道具 举报
class Ticket implements Runnable
{
        private int tick=100;
        Object obj1=new Object();
         Object obj2=new Object();
        public void run()
        {
                while(true)
                {
                        synchronized(obj1)
                        {
                                if(tick>0)
                                {
                                        try{
                                           //Thread.wait(); //如果线程1在这里等待了,他会把同步的锁释放掉,别的线程也能够拿到锁进来
                                         //Thread.sleep(10);//如果线程1来了睡100毫秒,他睡着的时候别的线程是进不了这个同步代码块的。
                                        System.out.println(Thread.currentThread().getName()+"....sale:"+tick--);
                                }
                               notifyAll();//唤醒所有线程
                        }synchronized(obj2)
                        {
                                if(tick>0)
                                {
                                        try{
                                           //Thread.wait(); //如果线程1在这里等待了,他会把同步的锁释放掉,别的线程也能够拿到锁进来
                                         //Thread.sleep(10);//如果线程1来了睡100毫秒,他睡着的时候别的线程是进不了这个同步代码块的。
                                        System.out.println(Thread.currentThread().getName()+"....sale:"+tick--);
                                }
                                notifyAll();//唤醒所有线程
                        }
                }
        }
}
class  TicketDemo
{
        public static void main(String[] args)
        {
                Ticket t=new Ticket();

                Thread t1=new Thread(t);
                Thread t2=new Thread(t);
                Thread t3=new Thread(t);
                Thread t4=new Thread(t);
                t1.start();
                t2.start();
                t3.start();
                t4.start();
               
        }
}


回复 使用道具 举报
能在详细点吗 谢谢
回复 使用道具 举报
wait();释放资源,释放锁。当一个线程执行到wait()是,会进入等待的环节,如果后面没有线程把它唤醒,他将永远等在那。如果有同步,当前线程拿着锁等待了,他会把锁释放掉。因为如果notify唤醒机制在同步的代码里。当前线程不释放锁就等待了,别的线程也进不去,就不能唤醒它了。所以它等待前释放锁。

sleep();释放资源,不释放锁。当一个线程执行到sleep()时,会睡眠相应的时间,时间到了自动就恢复运行了。如果有同步的话,当前线程执行sleep()后就拿着锁睡眠了,别的线程也无法进入同步的区域,因为无法获取到锁。
回复 使用道具 举报
13、sleep() 和 wait() 有什么区别?
     (网上的答案:sleep是线程类(Thread)的方法,导致此线程暂停执行指定时间,给执行机会给其他线程,但是监控状态依然保持,到时后会自动恢复。调用sleep不会释放对象锁。 wait是Object类的方法,对此对象调用wait方法导致本线程放弃对象锁,进入等待此对象的等待锁定池,只有针对此对象发出notify方法(或notifyAll)后本线程才进入对象锁定池准备获得对象锁进入运行状态。)

sleep就是正在执行的线程主动让出cpu,cpu去执行其他线程,在sleep指定的时间过后,cpu才会回到这个线程上继续往下执行,如果当前线程进入了同步锁,sleep方法并不会释放锁,即使当前线程使用sleep方法让出了cpu,但其他被同步锁挡住了的线程也无法得到执行。wait是指在一个已经进入了同步锁的线程内,让自己暂时让出同步锁,以便其他正在等待此锁的线程可以得到同步锁并运行,只有其他线程调用了notify方法(notify并不释放锁,只是告诉调用过wait方法的线程可以去参与获得锁的竞争了,但不是马上得到锁,因为锁还在别人手里,别人还没释放。如果notify方法后面的代码还有很多,需要这些代码执行完后才会释放锁,可以在notfiy方法后增加一个等待和一些代码,看看效果),调用wait方法的线程就会解除wait状态和程序可以再次得到锁后继续向下运行。对于wait的讲解一定要配合例子代码来说明,才显得自己真明白。
package com.huawei.interview;

public class MultiThread {

        /**
         * @param args
         */
        public static void main(String[] args) {
                // TODO Auto-generated method stub
                new Thread(new Thread1()).start();
                try {
                        Thread.sleep(10);
                } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                }
                new Thread(new Thread2()).start();               
        }
       
       
        private static class Thread1 implements Runnable
        {

                @Override
                public void run() {
                        // TODO Auto-generated method stub
//由于这里的Thread1和下面的Thread2内部run方法要用同一对象作为监视器,我们这里不能用this,因为在Thread2里面的this和这个Thread1的this不是同一个对象。我们用MultiThread.class这个字节码对象,当前虚拟机里引用这个变量时,指向的都是同一个对象。
                        synchronized (MultiThread.class) {

                                System.out.println("enter thread1...");
                               
                                System.out.println("thread1 is waiting");
                                try {
                        //释放锁有两种方式,第一种方式是程序自然离开监视器的范围,也就是离开了synchronized关键字管辖的代码范围,另一种方式就是在synchronized关键字管辖的代码内部调用监视器对象的wait方法。这里,使用wait方法释放锁。
                                        MultiThread.class.wait();
                                } catch (InterruptedException e) {
                                        // TODO Auto-generated catch block
                                        e.printStackTrace();
                                }
                               
                                System.out.println("thread1 is going on...");
                                System.out.println("thread1 is being over!");                       
                        }
                }
               
        }
       
        private static class Thread2 implements Runnable
        {

                @Override
                public void run() {
                        // TODO Auto-generated method stub
                        synchronized (MultiThread.class) {
                       
                                System.out.println("enter thread2...");
                               
                                System.out.println("thread2 notify other thread can release wait status..");
//由于notify方法并不释放锁, 即使thread2调用下面的sleep方法休息了10毫秒,但thread1仍然不会执行,因为thread2没有释放锁,所以Thread1无法得不到锁。

                                MultiThread.class.notify();
                               
                                System.out.println("thread2 is sleeping ten millisecond...");
                                try {
                                        Thread.sleep(10);
                                } catch (InterruptedException e) {
                                        // TODO Auto-generated catch block
                                        e.printStackTrace();
                                }
                               
                                System.out.println("thread2 is going on...");
                                System.out.println("thread2 is being over!");
                               
                        }
                }
               
        }       

}
-----------------------------------------------------
摘自:张孝祥面试题大全
回复 使用道具 举报
能举出实例吗?我就是想知道用在不同的程序中 结果有什么区别 谢谢
回复 使用道具 举报
简单的说吧,sleep();是睡眠状态,在规定的时间内自动回复正常状态,,wait();是线程等待状态,需要
notiry();唤醒才能回复正常状态。。。
回复 使用道具 举报
sleep是线程被调用时,占着cpu去睡觉,其他线程不能占用cpu,os认为该线程正在工作,不会让出系统资源,wait是进入等待池等待,让出系统资源,其他线程可以占用cpu,一般wait不会加时间限制,因为如果wait的线程运行资源不够,再出来也没用,要等待其他线程调用notifyall方法唤醒等待池中的所有线程,才会在进入就绪序列等待os分配系统资源,
sleep是静态方法,是谁掉的谁去睡觉,就算是在main线程里调用了线程b的sleep方法,实际上还是main去睡觉,想让线程b去睡觉要在b的代码中掉sleep

sleep(100L)是占用cpu,线程休眠100毫秒,其他进程不能再占用cpu资源,wait(100L)是进入等待池中等待,交出cpu等系统资源供其他进程使用,在这100毫秒中,该线程可以被其他线程notify,但不同的是其他在等待池中的线程不被notify不会出来,但这个线程在等待100毫秒后会自动进入就绪队列等待系统分配资源,换句话说,sleep(100)在100毫秒后肯定会运行,但wait在100毫秒后还有等待os调用分配资源,所以wait100的停止运行时间是不确定的,但至少是100毫秒。
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马