学习时正好碰到这两个方法,就查阅相关资料,并通过程序实现,进行区别一下:

1、每个对象都有一个锁来控制同步访问,Synchronized关键字可以和对象的锁交互,来实现同步方法或同步块。sleep()方法正在执行的线程主动让出CPU(然后CPU就可以去执行其他任务),在sleep指定时间后CPU再回到该线程继续往下执行(注意:sleep方法只让出了CPU,而并不会释放同步资源锁!!!);wait()方法则是指当前线程让自己暂时退让出同步资源锁,以便其他正在等待该资源的线程得到该资源进而运行,只有调用了notify()方法,之前调用wait()的线程才会解除wait状态,可以去参与竞争同步资源锁,进而得到执行。(注意:notify的作用相当于叫醒睡着的人,而并不会给他分配任务,就是说notify只是让之前调用wait的线程有权利重新参与线程的调度);

2、sleep()方法可以在任何地方使用;wait()方法则只能在同步方法或同步块中使用;

3、sleep()是线程线程类(Thread)的方法,调用会暂停此线程指定的时间,但监控依然保持,不会释放对象锁,到时间自动恢复;wait()是Object的方法,调用会放弃对象锁,进入等待队列,待调用notify()/notifyAll()唤醒指定的线程或者所有线程,才会进入锁池,不再次获得对象锁才会进入运行状态;

以程序说明:


  1. public class MultiThread {
  2. private static class Thread1 implements Runnable{
  3. @Override
  4. public void run() {
  5. //由于 Thread1和下面Thread2内部run方法要用同一对象作为监视器,如果用this则Thread1和Threa2的this不是同一对象
  6. //所以用MultiThread.class这个字节码对象,当前虚拟机里引用这个变量时指向的都是同一个对象
  7. synchronized(MultiThread.class){
  8. System.out.println("enter thread1 ...");
  9. System.out.println("thread1 is waiting");
  10. try{
  11. //释放锁有两种方式:(1)程序自然离开监视器的范围,即离开synchronized关键字管辖的代码范围
  12. //(2)在synchronized关键字管辖的代码内部调用监视器对象的wait()方法。这里使用wait方法
  13. MultiThread.class.wait();
  14. }catch(InterruptedException e){
  15. e.printStackTrace();
  16. }
  17. System.out.println("thread1 is going on ...");
  18. System.out.println("thread1 is being over!");
  19. }
  20. }
  21. }
  22. private static class Thread2 implements Runnable{
  23. @Override
  24. public void run() {
  25. //notify方法并不释放锁,即使thread2调用了下面的sleep方法休息10ms,但thread1仍然不会执行
  26. //因为thread2没有释放锁,所以Thread1得不到锁而无法执行
  27. synchronized(MultiThread.class){
  28. System.out.println("enter thread2 ...");
  29. System.out.println("thread2 notify other thread can release wait status ...");
  30. MultiThread.class.notify();
  31. System.out.println("thread2 is sleeping ten millisecond ...");
  32. try{
  33. Thread.sleep(10);
  34. }catch(InterruptedException e){
  35. e.printStackTrace();
  36. }
  37. System.out.println("thread2 is going on ...");
  38. System.out.println("thread2 is being over!");
  39. }
  40. }
  41. }
  42. public static void main(String[] args) {
  43. new Thread(new Thread1()).start();
  44. try{
  45. Thread.sleep(10);
  46. }catch(InterruptedException e){
  47. e.printStackTrace();
  48. }
  49. new Thread(new Thread2()).start();
  50. }
  51. }

程序运行结果如下图所示

小结:

在面试的时候,我们经常会遇到一个问题:sleep()方法与wait()方法区别。二者的作用都是进行等待。区别在于

1、sleep()方法是Thread对象中定义的方法,而wait()方法定义在Object类中

2、可以在任意地方调用线程对象的sleep方法,但是wait()方法必须位于同步代码块或者同步方法中

3、线程在sleep的时候,并不会释放锁,因此其他线程无法获取到锁,因此也无法执行。而wait方法在执行的时候会释放锁,因此其他线程可以获取到锁,可以有机会运行。

Java中sleep()与wait()区别的更多相关文章

  1. java中ArrayList 、LinkList区别

    转自:http://blog.csdn.net/wuchuanpingstone/article/details/6678653 个人建议:以下这篇文章,是从例子说明的方式,解释ArrayList.L ...

  2. java 中 ==和equals 的区别

      Java中equals和==的区别 java中的数据类型,可分为两类: 1.基本数据类型,也称原始数据类型.byte,short,char,int,long,float,double,boolea ...

  3. java中equals和==的区别 (转)

    java中equals和==的区别  值类型是存储在内存中的堆栈(以后简称栈),而引用类型的变量在栈中仅仅是存储引用类型变量的地址,而其本身则存储在堆中. ==操作比较的是两个变量的值是否相等,对于引 ...

  4. 【转】Java中equals和==的区别

    [转]Java中equals和==的区别 java中的数据类型,可分为两类: 1.基本数据类型,也称原始数据类型.byte,short,char,int,long,float,double,boole ...

  5. java中a++与++a区别

    java中a++与++a区别 a++与++a的区别,如果单独使用没有任何区别,如果在运算中就有区别了,a++是先运算在赋值,而++a是先赋值在运算!! 先看a++的代码哦 class demo1 { ...

  6. c#与java中byte字节的区别及转换方法

    原文:c#与java中byte字节的区别及转换方法 在java中  byte的范围在 [-128,127] 在C#中  byte的范围在 [0,255] 所以 java程序与C#程序 进行数据传输的时 ...

  7. java中==与equel的区别

    值类型是存储在内存中的堆栈(以后简称栈),而引用类型的变量在栈中仅仅是存储引用类型变量的地址,而其本身则存储在堆中. ==操作比较的是两个变量的值是否相等,对于引用型变量表示的是两个变量在堆中存储的地 ...

  8. Java中的“&”和“&&”的区别

    Java中的"&"和"&&"的区别 1."&"是位运算符,"&&"是逻辑 ...

  9. java中PriorityBlockingQueue 和DelayedWorkQueue 区别

    java中PriorityBlockingQueue 和DelayedWorkQueue 区别

  10. Java-杂项: Java中Array和ArrayList区别

    ylbtech-Java-杂项: Java中Array和ArrayList区别 1.返回顶部 1. 1)精辟阐述:可以将 ArrayList想象成一种“会自动扩增容量的Array”. 2)Array( ...

随机推荐

  1. 【习题 7-6 UVA - 12113】Overlapping Squares

    [链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 先预处理出来一个正方形. 然后每次枚举新加的正方形左上角的坐标就可以. 注意覆盖的规则,控制一下就可以. 然后暴力判断是否相同. 暴 ...

  2. amazeui学习笔记三(你来我往1)--常见问题FAQs

    amazeui学习笔记三(你来我往1)--常见问题FAQs 一.总结 1.DOM事件失败:记得加上初始化代码,例如 图片轮播 $('#my-slider').flexslider(); 2.jquer ...

  3. 数值溢出(arithmetic overflow)问题与解决方案

    0. 典型场景 两数相加(乘法).两数相减.一个数的阶乘,一个数的幂,这些统统可能造成数值的溢出: 避免数值溢出的方法: 当把一个计算出的很大的数赋值给一个 int(2^31-1)类型变量存储时,一般 ...

  4. 24. Spring Boot 事务的使用

    转自:https://blog.csdn.net/catoop/article/details/50595702

  5. JSP中的EL表达式详细介绍

    一.JSP EL语言定义 EL 提供了在 JSP 脚本编制元素范围外使用运行时表达式的功能.脚本编制元素是指页面中能够用于在 JSP 文件中嵌入 Java 代码的元素.它们通常用于对象操作以及执行那些 ...

  6. MyCat中间件:读写分离(转)

    利用MyCat中间件实现读写分离 需要两步: 1.搭建MySQL主从复制环境 2.配置MyCat读写分离策略 一.搭建MySQL主从环境 参考上一篇博文:MySQL系列之七:主从复制 二.配置MyCa ...

  7. Android Studio - no debuggable applications 的解决的方法

    之前logcat总是无法显示调试应用的信息 曾经我都是卸载重装.后来发如今StackOverflow有一个哥们说的非常对.一次就成功. 原话是这么说的: You also should have To ...

  8. Qt产生随机数(两种方法)

    第一种方法 #include <QTime> QTime time; time= QTime::currentTime(); qsrand(time.msec()+time.second( ...

  9. UVA 11090 Going in Cycle!!(Bellman-Ford推断负圈)

    题意:给定一个n个点m条边的加权有向图,求平均权值最小的回路. 思路:使用二分法求解.对于每个枚举值mid,推断每条边权值减去mid后有无负圈就可以. #include<cstdio> # ...

  10. 重构——DataTable转泛型

         泛型简单介绍         泛型能够最大限度的重用代码.保护类型的安全.提高性能.         泛型最常见的用途是创建集合类         泛型数据类型中使用的信息可在执行时通过反射 ...