一、

sleep 是线程类(Thread)的方法,导致此线程暂停执行指定时间,给执行机会给其他线程,但是监控状态依然保持,到时后会自动恢复,调用sleep 不会释放对象锁。由于没有释放对象锁,所以不能调用里面的同步方法。

sleep()使当前线程进入停滞状态(阻塞当前线程),让出CUP的使用、目的是不让当前线程独自霸占该进程所获的CPU资源,以留一定时间给其他线程执行的机会;
sleep()是Thread类的Static(静态)的方法;因此他不能改变对象的机锁,所以当在一个Synchronized块中调用Sleep()方法是,线程虽然休眠了,但是对象的机锁并木有被释放,其他线程无法访问这个对象(即使睡着也持有对象锁)。
在sleep()休眠时间期满后,该线程不一定会立即执行,这是因为其它线程可能正在运行而且没有被调度为放弃执行,除非此线程具有更高的优先级。

wait()方法是Object类里的方法;当一个线程执行到wait()方法时,它就进入到一个和该对象相关的等待池中,同时失去(释放)了对象的机锁(暂时失去机锁,wait(long timeout)超时时间到后还需要返还对象锁);可以调用里面的同步方法,其他线程可以访问;
wait()使用notify或者notifyAlll或者指定睡眠时间来唤醒当前等待池中的线程。
wiat()必须放在synchronized block中,否则会在program runtime时扔出”java.lang.IllegalMonitorStateException“异常。

二、

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()方法而产生

三 、

这两者的施加者是有本质区别的. 
sleep()是让某个线程暂停运行一段时间,其控制范围是由当前线程决定,也就是说,在线程里面决定.好比如说,我要做的事情是 "点火->烧水->煮面",而当我点完火之后我不立即烧水,我要休息一段时间再烧.对于运行的主动权是由我的流程来控制.

而wait(),首先,这是由某个确定的对象来调用的,将这个对象理解成一个传话的人,当这个人在某个线程里面说"暂停!",也是 thisOBJ.wait(),这里的暂停是阻塞,还是"点火->烧水->煮饭",thisOBJ就好比一个监督我的人站在我旁边,本来该线 程应该执行1后执行2,再执行3,而在2处被那个对象喊暂停,那么我就会一直等在这里而不执行3,但正个流程并没有结束,我一直想去煮饭,但还没被允许, 直到那个对象在某个地方说"通知暂停的线程启动!",也就是thisOBJ.notify()的时候,那么我就可以煮饭了,这个被暂停的线程就会从暂停处 继续执行.

其实两者都可以让线程暂停一段时间,但是本质的区别是一个线程的运行状态控制,一个是线程之间的通讯的问题

在java.lang.Thread类中,提供了sleep(),
而java.lang.Object类中提供了wait(), notify()和notifyAll()方法来操作线程
sleep()可以将一个线程睡眠,参数可以指定一个时间。
而wait()可以将一个线程挂起,直到超时或者该线程被唤醒。
    wait有两种形式wait()和wait(milliseconds).
sleep和wait的区别有:
  1,这两个方法来自不同的类分别是Thread和Object
  2,最主要是sleep方法没有释放锁,而wait方法释放了锁,使得其他线程可以使用同步控制块或者方法。
  3,wait,notify和notifyAll只能在同步控制方法或者同步控制块里面使用,而sleep可以在
    任何地方使用
   synchronized(x){
      x.notify()
     //或者wait()
   }
   4,sleep必须捕获异常,而wait,notify和notifyAll不需要捕获异常

四、下面用生产者和消费者举例

 package ProducterOrCustomer;

 public class ThreadDemo {

     public static void main(String[] args) {

         Food food = new Food();

         Thread thread1 = new Thread(new Customer(food));  //消费者线程
Thread thread2 = new Thread(new Producter(food)); //生产者线程 thread1.start();
thread2.start();
} }
 package ProducterOrCustomer;

 //  消费者
public class Customer implements Runnable{ private Food food; public Customer(Food food){
this.food = food;
} @Override
public void run(){
for (int i = 0; i < 3; i++){
food.get();
}
}
}
 package ProducterOrCustomer;

 // 生产者
public class Producter implements Runnable{ private Food food; public Producter(Food food){
this.food = food;
} @Override
public void run(){
for (int i = 0; i < 2; i++){
if (i%2 == 0){
food.set("红烧肉","好吃");
}else {
food.set("八宝鸭","都是米饭没鸭");
}
}
}
}
 package ProducterOrCustomer;

 public class Food {

     private String foodName;

     private String foodTaste;

     private Boolean flag = true;

     /** 初始值flag = true时,set()所在的线程处于正常执行状态,get()所在的线程处于wait()状态被挂起,
* 当执行到set()方法的34行时,flag = false,get()所造的线程被唤醒,这时,set()所造的线程处于wait()状态被挂起,
* 依次循环,所以每次都是先生产再消费,这就是生产者与消费者模式
*/ //生产
public synchronized void set(String foodName,String foodTaste){
if (!flag ){
try {
this.wait(); //当前线程进入等待状态,并让出CPU,并且释放监视器的锁
}catch (InterruptedException e){
e.printStackTrace();
}
}
System.out.println("生产 " + foodName + " " + foodTaste);
this.setFoodName(foodName);
this.setFoodTaste(foodTaste);
try {
Thread.sleep(500); //当前线程进入等待状态,让出cpu,不释放锁
}catch (InterruptedException e){
e.printStackTrace();
}
flag = false;
this.notify();
} //消费
public synchronized void get(){
if (flag){
try {
this.wait();
}catch (InterruptedException e){
e.printStackTrace();
}
}
System.out.println("消费"+this.foodName + " " + this.foodTaste); try {
Thread.sleep(500);
}catch (InterruptedException e){
e.printStackTrace();
}
flag = true;
this.notify();
} public Food(){ } public Food(String foodName,String foodTaste){
this.foodName = foodName;
this.foodTaste = foodTaste;
} public String getFoodName() {
return foodName;
} public void setFoodName(String foodName) {
this.foodName = foodName;
} public String getFoodTaste() {
return foodTaste;
} public void setFoodTaste(String foodTaste) {
this.foodTaste = foodTaste;
} public Boolean getFlag() {
return flag;
} public void setFlag(Boolean flag) {
this.flag = flag;
}
}

JAVA线程sleep和wait方法区别的更多相关文章

  1. JAVA线程sleep和wait方法区别 代码

    package test; import java.util.Date; import java.util.Random; public class test { public static void ...

  2. Java线程死锁查看分析方法

    如何查看是否有Java线程死锁?下面介绍两种方法. 一.Jconsole        Jconsole是JDK自带的图形化界面工具,使用JDK给我们的的工具JConsole,可以通过打开cmd然后输 ...

  3. Java线程Run和Start的区别

    先上结论:run只是Thread里面的一个普通方法,start是启动线程的方法.何以见得呢?可以执行下面的代码看看run和start的区别: package com.basic.thread; /** ...

  4. Java线程—-Runnable和Callable的区别和联系

    Java 提供了三种创建线程的方法 1.继承Thread接口 public class Thread2Thread { public static void main(String[] args) { ...

  5. 停止Java线程,小心interrupt()方法

    来源:http://blog.csdn.net/wxwzy738/article/details/8516253 程序是很简易的.然而,在编程人员面前,多线程呈现出了一组新的难题,如果没有被恰当的解决 ...

  6. 模拟做饭系统(java+线程中的join方法)

    (一)项目框架分析 妈妈要去做饭,发现没有酱油,让儿子去买酱油,然后回来做饭. 根据面向对象的思想,有两个对象,妈妈和儿子 主要有两个方法: (一)没有线程控制(即儿子没有买酱油回来妈妈就做好饭了)+ ...

  7. java线程中yield(),sleep(),wait()区别详解

    1.sleep() 使当前线程(即调用该方法的线程)暂停执行一段时间,让其他线程有机会继续执行,但它并不释放对象锁.也就是说如果有synchronized同步快,其他线程仍然不能访问共享数据.注意该方 ...

  8. Java 线程安全的实现方法

    概述 在软件业发展的初期,程序编写都是以算法为核心的,程序员会把数据和过程分别作为独立的部分来考虑,数据代表问题空间中的客体, 程序代码则用于处理这些数据,这种思维方式直接站在计算机的角度去抽象问题和 ...

  9. java线程学习之join方法

    join()方法表示一个线程要加入另一个线程,直到被加入的线程执行完毕. 这个概念不好理解的话看面这个例子 public class TestJoin { public static void mai ...

随机推荐

  1. Java经典编程题50道之三十一

    将一个数组逆序输出. public class Example31 {    public static void main(String[] args) {        int[] a = { 9 ...

  2. Thinkpad USB 经典键盘使用体验

    先上图,这就是一个键盘,不是笔记本电脑. 优点: 1. 键盘完胜各类巧克力式键盘. 2. 小红点和老thinkpad 上的小红点一样好用. 3. ESC 和Delete 放大后,盲摸很方便. 缺点: ...

  3. 有状态InheritableThreadLocal 配合 JDK8 ,异步方法调用

    我们可以把一个类的作用域注解为 @Scope(scopeName = WebApplicationContext.SCOPE_SESSION, proxyMode = ScopedProxyMode. ...

  4. 吾八哥学Selenium(三):操作复选框checkbox/单选框radio的方法

    复选框checkbox和单选框radio是web网站里经常会使用到的两个控件,那么在web自动化测试的时候如何利用Selenium来操作这俩控件呢?今天我们就来简单入门练习一下! html测试页面代码 ...

  5. 对ios、android开发程序员的14条忠告

    ————————本文摘自千锋教育(http://www.mobiletrain.org/)对ios\android开发程序员的14条忠告————————— 1.不要害怕在工作中学习. 只要有电脑,就可 ...

  6. 移动端-手机端-日历选择控件(支持Zepto和JQuery)

    一. 效果图 二. 功能说明 1. 支持切换年份,月份. 2. 支持点击选中日期,也可以点击确定选择日期. 三. 使用方法 1. 添加Input 在你的页面中添加Input输入框.可以再html里,也 ...

  7. NLP+VS=>Image Caption︱自动生成图像标题技术论文+相关项目

    读聪明人的笔记,是不是也能变聪明呢? Image Caption是一个融合计算机视觉.自然语言处理和机器学习的综合问题,它类似于翻译一副图片为一段描述文字. Image Caption问题可以定义为二 ...

  8. WIN7下PS/2等键盘失灵无法使用的解决办法

    WIN7下PS/2等键盘失灵无法使用的解决办法 装了win7,无意中一天开机,发现键盘不能用了.开始以为键盘坏了,重启看机,一看能进bios,各键正常.然后再重启,进系统,看设备管理器,发现键盘为黄色 ...

  9. mysql学习笔记02 表的操作

    创建数据表create  table table_name(//定义表的列的结构)创建表 先分析需要保存的实体数据,荣有哪些属性,这些属性应该有哪些属性列的定义 列名 列的数据类型 {} 进行表操作时 ...

  10. Activiti 实战篇 小试牛刀

    原文地址:http://blog.csdn.net/qq_30739519/article/details/51166062 1:工作流的概念   说明: 1) 假设:这两张图就是华谊兄弟的请假流程图 ...