1、两者的区别

对于sleep()方法,我们首先要知道该方法是属于Thread类中的。而wait()方法,则是属于Object类中的。

  • 这两个方法来自不同的类分别是Thread和Object
  • 最主要是sleep方法没有释放锁,而wait方法释放了锁,使得其他线程可以使用同步控制块或者方法(锁代码块和方法锁)。
  • wait,notify和notifyAll只能在同步控制方法或者同步控制块里面使用,而sleep可以在任何地方,任何时候被任何线程使用(使用范围)
  • sleep必须捕获异常,而wait,notify和notifyAll不需要捕获异常
  • sleep方法属于Thread类中方法,表示让一个线程进入睡眠状态,等待一定的时间之后,自动醒来进入到可运行状态,不会马上进入运行状态,因为线程调度机制恢复线程的运行也需要时间,一个线程对象调用了sleep方法之后,并不会释放他所持有的所有对象锁,所以也就不会影响其他进程对象的运行。但在调用sleep方法的过程中有可能被其他对象调用它的interrupt(),产生InterruptedException异常,如果你的程序不捕获这个异常,线程就会异常终止,进入TERMINATED状态,如果你的程序捕获了这个异常,那么程序就会继续执行catch语句块(可能还有finally语句块)以及以后的代码。
  • 注意sleep()方法是一个静态方法,也就是说他只对当前对象有效,通过t.sleep()让t对象进入sleep,这样的做法是错误的,它只会是使当前线程被sleep 而不是t线程
  • wait属于Object的成员方法,一旦一个对象调用了wait方法,必须要采用notify()和notifyAll()方法唤醒该进程;如果线程拥有某个或某些对象的同步锁,那么在调用了wait()后,这个线程就会释放它持有的所有同步资源,而不限于这个被调用了wait()方法的对象。wait()方法也同样会在wait的过程中有可能被其他对象调用interrupt()方法而产生

如果线程A希望立即结束线程B,则可以对线程B对应的Thread实例调用interrupt方法。如果此刻线程B正在wait/sleep/join,则线程B会立刻抛出InterruptedException,在catch() {} 中直接return即可安全地结束线程。

需要注意的是,InterruptedException是线程自己从内部抛出的,并不是interrupt()方法抛出的。对某一线程调用interrupt()时,如果该线程正在执行普通的代码,那么该线程根本就不会抛出InterruptedException。但是,一旦该线程进入到wait()/sleep()/join()后,就会立刻抛出InterruptedException。

waite()和notify()因为会对对象的“锁标志”进行操作,所以它们必须在synchronized函数或synchronized block中进行调用。如果在non-synchronized函数或non-synchronizedblock中进行调用,虽然能编译通过,但在运行时会发生illegalMonitorStateException的异常。

补充两个重要的方法:yield()和join()

yield方法

暂停当前正在执行的线程对象。

yield()方法是停止当前线程,让同等优先权的线程或更高优先级的线程有执行的机会。如果没有的话,那么yield()方法将不会起作用,并且由可执行状态后马上又被执行。

join方法是用于在某一个线程的执行过程中调用另一个线程执行,等到被调用的线程执行结束后,再继续执行当前线程。如:t.join();//主要用于等待t线程运行结束,若无此句,main则会执行完毕,导致结果不可预测。

说一下为什么使用wait()方法时,一般是需要while循环而不是if?

while(!执行条件) {
wait();
}
.... if(!执行条件) {
wait();
}
....

while会一直执行循环,直到条件满足,执行条件才会继续往下执行。if只会执行一次判断条件,不满足就会等待。这样就会出现问题。

我们知道用notify() 和notifyAll()可以唤醒线程,一般我们常用的是notifyAll(),因为notify(),只会随机唤醒一个睡眠线程,并不一定是我们想要唤醒的线程。如果使用的是notifyAll(),唤醒所有的线程,那你怎么知道他想唤醒的是某个正在等待的wait()线程呢,如果用while()方法,就会再次判断条件是不是成立,满足执行条件了,就会接着执行,而if会直接唤醒wait()方法,继续往下执行,根本不管这个notifyAll()是不是想唤醒的是自己还是别人,可能此时if的条件根本没成立。

举个例子:

while去水果店买苹果,没有了,然后while就和水果店老板说,有水果的时候通知我,我先回去了。if也去水果店买苹果,没有了,然后if就和水果店老板说,有水果的时候通知我,我先回去了。过一段时间,水果店老板发短信告诉while和if,有水果了,while去一看,水果店只是进了香蕉,并不是苹果,所以不是想要的水果,于是回去继续等水果店老板通知,而if根本就不看是不是自己想要的苹果,直接就叫老板送10斤水果过来,这样会导致你得到错误的结果。

Java中sleep方法和wait的详细区别的更多相关文章

  1. java中equals方法和hashcode方法的区别和联系,以及为什么要重写这两个方法,不重写会怎样

    一.在Object类中的定义为:public native int hashCode();是一个本地方法,返回的对象的地址值.但是,同样的思路,在String等封装类中对此方法进行了重写.方法调用得到 ...

  2. Java 中 sleep 方法和 wait 方法的区别?

    虽然两者都是用来暂停当前运行的线程,但是 sleep() 实际上只是短暂停顿,因为它不会释放锁,而 wait() 意味着条件等待,这就是为什么该方法要释放锁,因为只有这样,其他等待的线程才能在满足条件 ...

  3. ExtJS中listener方法和handler方法的区别

    listener方法和handler方法的区别在文档中的说明的太玄乎了,看不懂 listeners监听能够对一个click Event事件添加任意多个的事件响应处理函数 而handler处理只能够通过 ...

  4. java中equals方法和contentEquals方法区别

    java中,String类里提供了两种字符串的比较方式(算上“==”应该是三种) String line1 = new String("0123456789"); String l ...

  5. Java中get()方法和set()方法如何使用?

    在java中,为了保证数据的安全性,我们会把数据定义为private等(私有.封装),如果想要调用就会用到set()方法与get方法或者构造函数方法.这里说的是第一种方法,set()与get(),既然 ...

  6. jquery中attr方法和prop方法的区别

    关于checked的属性,最重要的概念就是你要记住,它跟checked的状态值是毫无关系的,设置checked = "checked"或者checked = "true& ...

  7. Thinkphp中D方法和M方法的区别

    两者共同点都是实例化模型的,而两者不同点呢?一起来看一下: $User = D('User');括号中的参数User,对应的模型类文件的 \Home\Model\UserModel.class.php ...

  8. java中paint方法和paintComponent方法的不同

    /* 1.由Component.java源代码中可以看见其中的paint()方法体是空的,在Container中重写了该方法,其子类Window等也重写了该方法 2.由JComponent.java源 ...

  9. java中构造方法和this,static关键字

    构造方法: 构造方法是一种特殊的方法,用于创建该类的对象,对对象的数据进行初始化 格式如下: [修饰符] 类名(形参列表){ 方法体 } 特点 A:方法名和类名相同  B:没有返回值类型,连void都 ...

随机推荐

  1. python3.6升级

    Ubuntu 14.04 and 16.04 If you are using Ubuntu 14.04 or 16.04, you can use Felix Krull's deadsnakes ...

  2. ecshop常见sql注入修复(转)

    ecshop系统部署在阿里云服务器上,阿里云提示Web-CMS漏洞: 修复方法如下: 0. /good.php 大概在第80行 $goods_id = $_REQUEST['id']; 修改为 $go ...

  3. Oracle 10g安装报错记录

    环境描述linux 5.6 安装Oracle 10.2.0.1.0 DBCA问题 1)DBCA图形化界面,出现乱码 测试环境,操作系统中文字符编码导致 export LANG=C 2)DBCA图形化点 ...

  4. 【linux】ARM板子开启浮点和neon加速

    参考 1. ARM平台NEON指令的编译和优化; 2. 交叉编译器 arm-linux-gnueabi 和 arm-linux-gnueabihf 的区别; 3. https://blog.csdn. ...

  5. Java匿名内部类的继承者、终结者————lambda表达式

    一.什么是lambda表达式? lambda表达式就是一个代码块,可以传入变量和放入相应的代码. 二.基本格式  (参数 ) - >{                      代码       ...

  6. 九度OJ-1112-导弹拦截-最长不增子序列

    题目1112:拦截导弹 时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:5218 解决:2603 题目描述: 某国为了防御敌国的导弹袭击,开发出一种导弹拦截系统.但是这种导弹拦截系统有一个缺 ...

  7. 软件安装配置笔记(一)——Oracle及PLSQL Developer的安装与配置

    一.Oracle: Oracle服务器端或桌面端可以创建本地的Oracle数据库,而Oracle客户端是用来远程连接其他服务器或电脑上的Oracle服务器端或桌面端的,安装客户端软件只需配置网络连接文 ...

  8. 如何在git上创建的本地仓库

    一.安装git(在git) 二. 三.输入个人信息(代码提交者) git config --global user.name "xxxx" git config --global ...

  9. POJ3070 Fibonacci(矩阵快速幂加速递推)【模板题】

    题目链接:传送门 题目大意: 求斐波那契数列第n项F(n). (F(0) = 0, F(1) = 1, 0 ≤ n ≤ 109) 思路: 用矩阵乘法加速递推. 算法竞赛进阶指南的模板: #includ ...

  10. P1373 小a和uim之大逃离(动态规划)

    题目链接:传送门 题目大意: 一个N行M列的矩阵,从任意点开始往右或者往下走,每走一格获得所到达的格子的分数. 要求总步数必须为偶数.问有多少种走法,使得奇数步得到的总分和偶数步得到的总分对K+1取模 ...