sleep 及 线程的协作 java wait、notify、notifyAll

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


       Java 中线程之间的协作是通过Object 的wait()方法和notify()方法来实现的,当一个线程执行到wait()方法时,它就进入到一个和该对象相关的等待池中,同时失去(释放)了对象的机锁(暂时失去对象锁,wait(long timeout)超时时间到后还需要返还对象锁);其他线程可以访问;

       wait()和sleep()都可以通过interrupt()方法打断线程的暂停状态,从而使线程立刻抛出InterruptedException(但不建议使用该方法)。

wait()与sleep()的区别:
1)sleep()方法是Thread 类的方法,而wait()方法是Object 的方法。
2)sleep()方法并不会释放对象的锁,而wait()方法的调用却释放对象的锁,可以通过notify()或notifyAll()方法可以再次获得对象的锁。

接着,简单介绍下wait()方法:
1)wait()方法与sleep()方法一样,可以接受一个毫秒数,当今过指定的时间之后对象将再一次的获得锁。
2)wait(),notify()和notifyAll()必须在同步控制方法或同步控制块中进行调用,否则将会抛出IllegalMonitorStateException异常。
3)在使用wait()方法时,应该将它嵌套在while 语句中,防止线程的意外唤醒(notifyAll 方法)。
   

     代码块如下

  synchronized(obj1)             //1.进入同步块   
  {   
          try   {   
          ...   
          obj1.wait();                 //2.进入暂停状态   
          }catch   (InterruptedException   exp)   {}   
  }   

     
  1.当前同步对象(monitor)为obj1,obj1是任一实例,若是同步方法,则同步对象是this.进入同步块后,obj1为锁定状态,锁定状态 对obj1本身无任何影响,而其它线程执行到同一代码时,因不能获得锁,处于Block状态,一旦解锁,被block的线程自动继续执行.  
  2.调用obj1.wait()有两个作用,一是使线程进入等待状态,二是解锁obj1,这时被block的线程将获得锁.线程1要退出等待必须要由其它线程显式的调用obj1.notify()或notifyAll()方法.   
  如   

  synchronized(obj1)   
  {   
          ...   
          obj1.notify();         //3.   向wait的线程发通知信息   
          ...   
  }  

 若其它线程执行到此时,线程1处于wait状态,则wait状态解除,解除后,若线程1若得到锁就能继续执行,若有多个线程处于obj1的wait状态,notify将随机选一个线程激活,而notifyAll是同时解除所有的wait状态.  

如果在同步块入口点阻塞,不须其它线程调用notify(),调了也没效果,同步块能自动获得锁   
如果是wait造成了阻塞,须用notfiy()激活,这两个方法是配合使用  

下面用具体的例子

 

package com.test;

import java.text.SimpleDateFormat;
import java.util.Date;

public class threadTest {
	public  void waitFunction(){
		synchronized(this)             //1.进入同步块      
		{      
		        try{ 
		        	System.out.println( "进入waitFunction" );
		        	this.wait();                 //2.进入暂停状态    
		        	System.out.println( "退出waitFunction" );
		        }catch   (InterruptedException   exp){
		        	
		        	
		        }      
		}    
	}
	public  void notifyFunction(){
		synchronized(this)             //1.进入同步块      
		{      
			    System.out.println( "进入notifyFunction" );
		        this.notify();                 //2.    
		        System.out.println( "退出notifyFunction" );
		}    
	}
	
	public  void sleepFunction(){
		synchronized(this)             //1.进入同步块      
		{      
		        try{ 
		        	System.out.println( "进入sleepFunction" );
		        	Thread.sleep( 9000 );                 //2.进入暂停状态    
		        	System.out.println( "退出sleepFunction" );
		        }catch   (InterruptedException   exp){
		        	
		        	
		        }      
		}    
	}
	public static void main(String args[]){
		final threadTest tt= new threadTest();
		final SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//设置日期格式
		new Thread(){ public void run(){
			
			System.out.println( "线程1 sleepFunction()"+df.format(new Date()));
			tt.sleepFunction();
			 
		 }  }.start(
		);
		
		new Thread(){ public void run(){
			System.out.println( "线程2 waitFunction()"+df.format(new Date()) );
			tt.waitFunction();
			 
		 }  }.start(
		);
		 
		 try {
			Thread.sleep(20000);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
			new Thread(){ public void run(){
				
				System.out.println( "线程3 notifyFunction()"+df.format(new Date()) );
				
				tt.notifyFunction();
				 
			 }  }.start(
			);
		
	}
   
}

 

线程1 sleepFunction()2013-03-28 15:24:45
线程2 waitFunction()2013-03-28 15:24:45
进入sleepFunction
退出sleepFunction
进入waitFunction
线程3 notifyFunction()2013-03-28 15:25:05
进入notifyFunction
退出notifyFunction
退出waitFunction

结果分析:

     (1):线程1执行时的sleepFunction,因sleep是要维持对象锁,其他线程无法访问其他的同步块。

     (2):线程2执行的waitFunction,当执行waitFunction时,sleep维持对象锁,所以无法执行同步块,直到sleep释放对象锁【即休眠时间过了,并执行相关代码】,才进入waitFunction同步块中,因此前面五步输出

线程1 sleepFunction()2013-03-28 15:24:45
线程2 waitFunction()2013-03-28 15:24:45
进入sleepFunction
退出sleepFunction
进入waitFunction

   (3):线程2执行 wait方法后,将释放锁资源,并进入等待状态,线程3执行的时候因线程2已经释放锁资源,因此就能进入同步块中,并执行notify方法,将wait状态线程唤醒,让wait线程完成继续的工作。这是为啥后4步输出为

线程3 notifyFunction()2013-03-28 15:25:05
进入notifyFunction
退出notifyFunction
退出waitFunction

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值