zoukankan      html  css  js  c++  java
  • JAVA线程sleep和wait方法区别

    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 com.day19;
    /**
     * 生产者与消费者线程
     * @author tenlee
     *
     */
    public class ThreadDemo {
    
    	public static void main(String[] args) {
    		Food food = new Food();
    		Producter p = new Producter(food);
    		Customer c = new Customer(food);
    		Thread tp = new Thread(p);
    		Thread tc = new Thread(c);
    		tp.start();
    		tc.start();
    	}
    }
    //生产者
    class Producter implements Runnable {
    	private Food food;
    	public Producter(Food food) {
    		this.food = food;
    	}
    	@Override
    	public void run() {
    		for(int i = 0; i < 50; i++) {
    			if(i % 2 == 0) {//偶数,生产xx菜
    //				System.out.println("红烧肉----生产");
    //				food.setName("红烧肉");
    //				try {
    //					Thread.sleep(500);//做菜
    //				} catch (InterruptedException e) {
    //					e.printStackTrace();
    //				}
    //				food.setEfficasy("好吃");
    				food.set("红烧肉", "好吃");
    				
    			} else {//奇数,生产xx菜
    //				System.out.println("脆皮鸡 生产");
    //				food.setName("脆皮鸡");
    //				try {
    //					Thread.sleep(500);//做菜
    //				} catch (InterruptedException e) {
    //					e.printStackTrace();
    //				}
    //				food.setEfficasy("香脆");
    				food.set("脆皮鸡", "香脆");
    			}
    		}
    	}
    }
    class Customer implements Runnable {
    	private Food food;
    	public Customer(Food food) {
    		this.food = food;
    	}
    	@Override
    	public void run() {
    		for(int i = 0; i < 50; i++){
    //			try {
    //				Thread.sleep(500);
    //			} catch (InterruptedException e) {
    //				// TODO Auto-generated catch block
    //				e.printStackTrace();
    //			}
    //			System.out.println(food.getName() + "--->"
    //					+ food.getEfficasy());
    			food.get();
    		}
    	}
    }
    
    package com.day19;
    
    class Food {
    	private String name;//菜名
    	private String efficasy;//功效
    	private boolean flag = true;
    	
    	public synchronized void set(String name, String efficasy) {
    		if(!flag) {//1, 消费,不能生产
    			try {
    				this.wait();//当前线程进入等待状态,并让出CPU,释放监视器的锁
    			} catch (InterruptedException e) {
    				e.printStackTrace();
    			}
    		}
    		System.out.println("shengchan " + name + " " + efficasy);
    		this.setName(name);
    		this.setEfficasy(efficasy);
    		try {
    			Thread.sleep(500);
    		} catch (InterruptedException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		}
    		flag = false; //开始消费
    		this.notify();
    	}
    	public synchronized void get() {
    		if(flag) {//true是生产
    			try {
    				this.wait();
    			} catch (InterruptedException e) {
    				// TODO Auto-generated catch block
    				e.printStackTrace();
    			}
    		}
    		System.out.println(this.getName() + "xiaofei-->" + this.getEfficasy());
    		try {
    			Thread.sleep(500);
    		} catch (InterruptedException e) {
    			e.printStackTrace();
    		}
    		flag = true; //开始生产
    		this.notify();
    	}
    	public Food() {
    		
    	}
    
    	public Food(String name, String efficasy) {
    		super();
    		this.name = name;
    		this.efficasy = efficasy;
    	}
    
    	public String getName() {
    		return name;
    	}
    
    	public void setName(String name) {
    		this.name = name;
    	}
    
    	public String getEfficasy() {
    		return efficasy;
    	}
    
    	public void setEfficasy(String efficasy) {
    		this.efficasy = efficasy;
    	}
    }
    

      

  • 相关阅读:
    docker国内镜像地址
    springBoot+websocket集群系列知识
    多个idea项目使用同一个tomcat
    nginx+tomcat遇到的https重定向到http问题
    设置常用错误页面自定义显示
    mysql关于索引的一些零碎知识点(持续更新)
    Idea使用Lombok简化实体类代码
    mysql索引分类及实现原理
    使用SpringSession和Redis解决分布式Session共享问题
    HashMap ConcurrentHashMap解读
  • 原文地址:https://www.cnblogs.com/tenlee/p/4940807.html
Copyright © 2011-2022 走看看