sleep和wait的异同点

相同点:sleep和wait都可以让线程进入阻塞状态

不同点:
1、wait()方法属于Object类,sleep()属于Thread类;

2、wait()方法释放cpu给其他线程,自己让出资源进入等待池等待;sleep占用cpu,不让出资源;

3、sleep()必须指定时间,wait()可以指定时间也可以不指定,如果时间不到只能调用interrupt()强行打断;sleep必须设置等待时间,sleep()时间到,线程处于就绪状态,等待系统调度;Thread.Sleep(0)的作用是“触发操作系统立刻重新进行一次CPU竞争”。

4、wait()方法会释放持有的锁,不然其他线程不能进入同步方法或同步块,从而不能调用notify(),notifyAll()方法来唤醒线程,产生死锁,所以释放锁,可以执行其他线程,也可以唤醒自己,只是设置停止自己的时间时不确定的;sleep方法不会释放持有的锁,设置sleep的时间是确定的会按时执行的;

5、wait()方法只能在同步方法或同步代码块中调用,否则会报illegalMonitorStateException异常,如果没有设定时间,使用notify()来唤醒;而sleep()能在任何地方调用;sleep必须捕获异常,而wait,notify和notifyAll不需要捕获异常

1 wait方法:
该方法属于Object的方法,wait方法的作用是使得当前调用wait方法所在部分(代码块)的线程停止执行,并释放当前获得的调用wait所在的代码块的锁,并在其他线程调用notify或者notifyAll方法时恢复到竞争锁状态(一旦获得锁就恢复执行)。

调用wait方法需要注意几点:
第一点:wait被调用的时候必须在拥有锁(即synchronized修饰的)的代码块中。
第二点:恢复执行后,从wait的下一条语句开始执行,因而wait方法总是应当在while循环中调用,以免出现恢复执行后继续执行的条件不满足却继续执行的情况。
第三点:若wait方法参数中带时间,则除了notify和notifyAll被调用能激活处于wait状态(等待状态)的线程进入锁竞争外,在其他线程中interrupt它或者参数时间到了之后,该线程也将被激活到竞争状态。
第四点:wait方法被调用的线程必须获得之前执行到wait时释放掉的锁重新获得才能够恢复执行。

2 notify方法和notifyAll方法:
notify方法通知调用了wait方法,但是尚未激活的一个线程进入线程调度队列(即进入锁竞争),注意不是立即执行。并且具体是哪一个线程不能保证。另外一点就是被唤醒的这个线程一定是在等待wait所释放的锁。
notifyAll方法则唤醒所有调用了wait方法,尚未激活的进程进入竞争队列。

3 synchronized关键字:
第一点:synchronized用来标识一个普通方法时,表示一个线程要执行该方法,必须取得该方法所在的对象的锁。
第二点:synchronized用来标识一个静态方法时,表示一个线程要执行该方法,必须获得该方法所在的类的类锁。
第三点:synchronized修饰一个代码块。类似这样:synchronized(obj) { //code…. }。表示一个线程要执行该代码块,必须获得obj的锁。这样做的目的是减小锁的粒度,保证当不同块所需的锁不冲突时不用对整个对象加锁。利用零长度的byte数组对象做obj非常经济。

java多线程是抢占式,而非分时制
挂起的原因可能是如下几种情况:
(1)通过调用sleep()方法使线程进入休眠状态,线程在指定时间内不会运行。
(2)通过调用join()方法使线程挂起,使自己等待另一个线程的结果,直到另一个线程执行完毕为止。
(3)通过调用wait()方法使线程挂起,直到线程得到了notify()和notifyAll()消息,线程才会进入“可执行”状态。

 Java中的多线程是一种抢占式的机制,而不是分时机制。抢占式的机制是有多个线程处于可运行状态,但是只有一个线程在运行。 

共同点:

  1. 他们都是在多线程的环境下,都可以在程序的调用处阻塞指定的毫秒数,并返回。
  2. wait()和sleep()都可以通过interrupt()方法 打断线程的暂停状态 ,从而使线程立刻抛出InterruptedException。
    如 果线程A希望立即结束线程B,则可以对线程B对应的Thread实例调用interrupt方法。如果此刻线程B正在wait/sleep/join,则 线程B会立刻抛出InterruptedException,在catch() {} 中直接return即可安全地结束线程。
    需要注意的 是,InterruptedException是线程自己从内部抛出的,并不是interrupt()方法抛出的。对某一线程调用 interrupt()时,如果该线程正在执行普通的代码,那么该线程根本就不会抛出InterruptedException。但是,一旦该线程进入到 wait()/sleep()/join()后,就会立刻抛出InterruptedException 。

猜你喜欢

转载自blog.csdn.net/qq_43473073/article/details/88934045
今日推荐