Java中sleep()与wait()区别
学习时正好碰到这两个方法,就查阅相关资料,并通过程序实现,进行区别一下:
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()唤醒指定的线程或者所有线程,才会进入锁池,不再次获得对象锁才会进入运行状态;
以程序说明:
-
public class MultiThread {
-
-
private static class Thread1 implements Runnable{
-
@Override
-
public void run() {
-
//由于 Thread1和下面Thread2内部run方法要用同一对象作为监视器,如果用this则Thread1和Threa2的this不是同一对象
-
//所以用MultiThread.class这个字节码对象,当前虚拟机里引用这个变量时指向的都是同一个对象
-
synchronized(MultiThread.class){
-
System.out.println("enter thread1 ...");
-
System.out.println("thread1 is waiting");
-
-
try{
-
//释放锁有两种方式:(1)程序自然离开监视器的范围,即离开synchronized关键字管辖的代码范围
-
//(2)在synchronized关键字管辖的代码内部调用监视器对象的wait()方法。这里使用wait方法
-
MultiThread.class.wait();
-
}catch(InterruptedException e){
-
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() {
-
//notify方法并不释放锁,即使thread2调用了下面的sleep方法休息10ms,但thread1仍然不会执行
-
//因为thread2没有释放锁,所以Thread1得不到锁而无法执行
-
synchronized(MultiThread.class){
-
System.out.println("enter thread2 ...");
-
System.out.println("thread2 notify other thread can release wait status ...");
-
MultiThread.class.notify();
-
System.out.println("thread2 is sleeping ten millisecond ...");
-
-
try{
-
Thread.sleep(10);
-
}catch(InterruptedException e){
-
e.printStackTrace();
-
}
-
-
System.out.println("thread2 is going on ...");
-
System.out.println("thread2 is being over!");
-
}
-
}
-
}
-
-
public static void main(String[] args) {
-
new Thread(new Thread1()).start();
-
try{
-
Thread.sleep(10);
-
}catch(InterruptedException e){
-
e.printStackTrace();
-
}
-
-
new Thread(new Thread2()).start();
-
}
-
-
}
程序运行结果如下图所示
小结:
在面试的时候,我们经常会遇到一个问题:sleep()方法与wait()方法区别。二者的作用都是进行等待。区别在于
1、sleep()方法是Thread对象中定义的方法,而wait()方法定义在Object类中
2、可以在任意地方调用线程对象的sleep方法,但是wait()方法必须位于同步代码块或者同步方法中
3、线程在sleep的时候,并不会释放锁,因此其他线程无法获取到锁,因此也无法执行。而wait方法在执行的时候会释放锁,因此其他线程可以获取到锁,可以有机会运行。
Java中sleep()与wait()区别的更多相关文章
- java中ArrayList 、LinkList区别
转自:http://blog.csdn.net/wuchuanpingstone/article/details/6678653 个人建议:以下这篇文章,是从例子说明的方式,解释ArrayList.L ...
- java 中 ==和equals 的区别
Java中equals和==的区别 java中的数据类型,可分为两类: 1.基本数据类型,也称原始数据类型.byte,short,char,int,long,float,double,boolea ...
- java中equals和==的区别 (转)
java中equals和==的区别 值类型是存储在内存中的堆栈(以后简称栈),而引用类型的变量在栈中仅仅是存储引用类型变量的地址,而其本身则存储在堆中. ==操作比较的是两个变量的值是否相等,对于引 ...
- 【转】Java中equals和==的区别
[转]Java中equals和==的区别 java中的数据类型,可分为两类: 1.基本数据类型,也称原始数据类型.byte,short,char,int,long,float,double,boole ...
- java中a++与++a区别
java中a++与++a区别 a++与++a的区别,如果单独使用没有任何区别,如果在运算中就有区别了,a++是先运算在赋值,而++a是先赋值在运算!! 先看a++的代码哦 class demo1 { ...
- c#与java中byte字节的区别及转换方法
原文:c#与java中byte字节的区别及转换方法 在java中 byte的范围在 [-128,127] 在C#中 byte的范围在 [0,255] 所以 java程序与C#程序 进行数据传输的时 ...
- java中==与equel的区别
值类型是存储在内存中的堆栈(以后简称栈),而引用类型的变量在栈中仅仅是存储引用类型变量的地址,而其本身则存储在堆中. ==操作比较的是两个变量的值是否相等,对于引用型变量表示的是两个变量在堆中存储的地 ...
- Java中的“&”和“&&”的区别
Java中的"&"和"&&"的区别 1."&"是位运算符,"&&"是逻辑 ...
- java中PriorityBlockingQueue 和DelayedWorkQueue 区别
java中PriorityBlockingQueue 和DelayedWorkQueue 区别
- Java-杂项: Java中Array和ArrayList区别
ylbtech-Java-杂项: Java中Array和ArrayList区别 1.返回顶部 1. 1)精辟阐述:可以将 ArrayList想象成一种“会自动扩增容量的Array”. 2)Array( ...
随机推荐
- 【习题 7-6 UVA - 12113】Overlapping Squares
[链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 先预处理出来一个正方形. 然后每次枚举新加的正方形左上角的坐标就可以. 注意覆盖的规则,控制一下就可以. 然后暴力判断是否相同. 暴 ...
- amazeui学习笔记三(你来我往1)--常见问题FAQs
amazeui学习笔记三(你来我往1)--常见问题FAQs 一.总结 1.DOM事件失败:记得加上初始化代码,例如 图片轮播 $('#my-slider').flexslider(); 2.jquer ...
- 数值溢出(arithmetic overflow)问题与解决方案
0. 典型场景 两数相加(乘法).两数相减.一个数的阶乘,一个数的幂,这些统统可能造成数值的溢出: 避免数值溢出的方法: 当把一个计算出的很大的数赋值给一个 int(2^31-1)类型变量存储时,一般 ...
- 24. Spring Boot 事务的使用
转自:https://blog.csdn.net/catoop/article/details/50595702
- JSP中的EL表达式详细介绍
一.JSP EL语言定义 EL 提供了在 JSP 脚本编制元素范围外使用运行时表达式的功能.脚本编制元素是指页面中能够用于在 JSP 文件中嵌入 Java 代码的元素.它们通常用于对象操作以及执行那些 ...
- MyCat中间件:读写分离(转)
利用MyCat中间件实现读写分离 需要两步: 1.搭建MySQL主从复制环境 2.配置MyCat读写分离策略 一.搭建MySQL主从环境 参考上一篇博文:MySQL系列之七:主从复制 二.配置MyCa ...
- Android Studio - no debuggable applications 的解决的方法
之前logcat总是无法显示调试应用的信息 曾经我都是卸载重装.后来发如今StackOverflow有一个哥们说的非常对.一次就成功. 原话是这么说的: You also should have To ...
- Qt产生随机数(两种方法)
第一种方法 #include <QTime> QTime time; time= QTime::currentTime(); qsrand(time.msec()+time.second( ...
- UVA 11090 Going in Cycle!!(Bellman-Ford推断负圈)
题意:给定一个n个点m条边的加权有向图,求平均权值最小的回路. 思路:使用二分法求解.对于每个枚举值mid,推断每条边权值减去mid后有无负圈就可以. #include<cstdio> # ...
- 重构——DataTable转泛型
泛型简单介绍 泛型能够最大限度的重用代码.保护类型的安全.提高性能. 泛型最常见的用途是创建集合类 泛型数据类型中使用的信息可在执行时通过反射 ...