zoukankan      html  css  js  c++  java
  • 线程间通信(等待,唤醒)&Java中sleep()和wait()比较

    1.什么是线程间通信?

      多个线程在处理同一资源,但是任务却不同

    生活中栗子:有一堆煤,有2辆车往里面送煤,有2辆车往外拉煤,这个煤就是同一资源,送煤和拉煤就是任务不同。

     2.等待/唤醒机制。

      涉及的方法:

      (1)wait(): 让线程处于冻结状态,被wait的线程会被存储到线程池(容器)中
      (2)notify():唤醒线程池中一个线程(任意).
      (3)notifyAll():唤醒线程池中的所有线程。

      这些方法都必须定义在同步中
      因为这些方法是用于操作线程状态的方法。
      必须要明确到底操作的是哪个锁上的线程。

      什么是线程池?

      顾名思义就是事先创建若干个可执行的线程放入一个池(容器)中,需要的时候从池中获取线程而不用自行创建,使用完毕后不需要销毁放入池中,从而减少创建和销毁对象的开销。


      为什么操作线程的方法wait notify notifyAll定义在了Object类中

      因为这些方法是监视器的方法。监视器其实就是锁,就是栗子中的r
      锁可以是任意的对象,任意的对象调用的方式一定定义在Object类中。

    栗子:(谁拿锁谁执行) 

    class Resource
    {
    	private String name;
    	private String sex;
    	private boolean flag = false;
    
    	public synchronized void set(String name,String sex)
    	{
    		if(flag)//为真的时候,就直接进入wait,这样该线程就释放了执行权了。为假就执行下面的语句
    			try{this.wait();}catch(InterruptedException e){}
    		this.name = name;
    		this.sex = sex;
    		flag = true;
    		this.notify();//唤醒输出线程,输出线程具备了执行资格。抢来了CPU执行权
    	}
    
    	public synchronized void out()
    	{
    		if(!flag)
    			try{this.wait();}catch(InterruptedException e){}
    		System.out.println(name+"...+...."+sex);
    		flag = false;
    		notify();//唤醒输入线程
    	}
    }
    
    //输入
    class Input implements Runnable
    {
    	Resource r ;
    //	Object obj = new Object();
    	Input(Resource r)
    	{
    		this.r = r;
    	}
    	public void run()
    	{
    		int x = 0;
    		while(true)
    		{
    			if(x==0)
    			{
    				r.set("mike","nan");
    			}
    			else
    			{
    				r.set("丽丽","女女女女女女");
    			}
    			x = (x+1)%2;
    		}
    	}
    }
    //输出
    class Output implements Runnable
    {
    
    	Resource r;
    //	Object obj = new Object();
    	Output(Resource r)
    	{
    		this.r = r;
    	}
    
    	public void run()
    	{
    		while(true)
    		{
    			r.out();
    		}
    	}
    }
    
    class  ResourceDemo3
    {
    	public static void main(String[] args) 
    	{
    		//创建资源。
    		Resource r = new Resource();
    		//创建任务。
    		Input in = new Input(r);
    		Output out = new Output(r);
    		//创建线程,执行路径。
    		Thread t1 = new Thread(in);
    		Thread t2 = new Thread(out);
    		//开启线程
    		t1.start();
    		t2.start();
    	}
    }

    3.sleep()和wait()比较

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

     (2)sleep()方法导致了程序暂停执行指定的时间,让出cpu该其他线程,但是他的监控状态依然保持着,当指定的时间到了又会自动恢复运行状态。

     (3)在调用sleep()方法的过程中,线程不会释放对象锁。

      而当调用wait()方法的时候,线程会放弃对象锁,进入等待此对象的等待锁定池,只有针对此对象调用notify()方法后本线程才进入对象锁定池准备获取对象锁进入运行状态。

     (4)wait可以指定时间也可以不指定时间,sleep必须指定时间

     (5)在同步中时,对cpu的执行权和锁的处理不同。
      wait:释放执行权,释放锁
      sleep:释放执行权,不释放锁

    栗子:

      关于sleep和wait,以下描述错误的是D

       A.sleep是线程类的方法,wait是object的方法

       B.sleep不释放对象锁,wait放弃对象锁

       C.sleep暂停线程,但监控状态依然保持,结束后会自动恢复

       D.wait进入等待锁定池,只有针对此对象发出notify方法获得对象锁进入运行状态

    原因:是D中,准备获取对象锁进入运行状态,而不是立即进入

    4.线程状态

  • 相关阅读:
    遇到的开发错误
    我的麦本本配置
    C#:100以内能被7整除的最大自然数
    C#:静态字段和静态方法的学习
    Oracle 备份、恢复单表或多表数据步骤 (转)
    有关关键路径的概念和算法 (转)
    Delphi中StringReplace函数的使用
    Delphi 里 FillChar的用法
    Delphi中destroy, free, freeAndNil, release用法和区别
    项目经理、系统架构师或技术骨干应该具备的水平
  • 原文地址:https://www.cnblogs.com/GumpYan/p/5744459.html
Copyright © 2011-2022 走看看