`

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

 

分享到:
评论

相关推荐

    java之wait,notify的用法([ 详解+实例 ])

    wait方法是Object类的一个方法,用于让当前线程进入等待状态,直到其他线程调用notify或notifyAll方法来唤醒它。在wait方法中,当前线程会释放它所占有的锁,并进入等待状态。wait方法可以带有参数,指定等待的时间...

    Java多线程wait和notify

    在Java中,`wait()` 和 `notify()` 方法是实现线程间通信和协作的重要工具,它们属于 `java.lang.Object` 类,这意味着所有类都默认继承了这两个方法。本文将详细探讨如何使用 `wait()` 和 `notify()` 来控制子线程...

    深入理解Wait、Notify和Wait与sleep区别

    首先,`wait()`, `notify()`和`notifyAll()`是Object类中的方法,它们主要用于线程间通信和协作。这些方法只能在同步环境中(如`synchronized`块或方法)使用,否则会抛出`IllegalMonitorStateException`。它们的...

    sleep() 方法和wait()方法的区别.docx

    wait() 方法可以通过 notify 或者 notifyAll 或者指定睡眠时间来唤醒当前等待池中的线程。 sleep() 和 wait() 方法的区别 sleep() 和 wait() 方法的最大区别是: 1. sleep() 睡眠时,保持对象锁,仍然占有该锁; ...

    wait和notifyAll方法的使用示例

    在Java多线程编程中,`wait()` 和 `notifyAll()` 方法是非常重要的同步机制,主要用于实现线程间的通信与同步控制。通过合理运用这些方法,可以有效地解决生产者消费者模型中的资源竞争问题。本文将结合具体的代码...

    多线程sleep,yield,wait区别

    `sleep()` 适用于需要让线程暂时退出执行的情况,`yield()` 用于尝试平衡多个线程的执行,而 `wait/notify/notifyAll()` 则用于线程间的协作,确保资源的有效共享。理解这些方法的差异和使用场景,能帮助开发者更好...

    Java线程中wait,await,sleep,yield,join用法总结.pdf

    public class ThreadWaitNotify { public static void main(String[] args) throws InterruptedException { DemoTest demoTest = new DemoTest(); // 使用线程池异步执行waitTest方法 ExecutorService ...

    一个理解wait()与notify()的例子

    本文旨在解析一个具体的Java多线程示例代码,以帮助读者更好地理解`wait()`与`notify()`方法的作用及其实现机制。这两个方法是Java中实现线程间通信的重要手段之一,尤其在解决生产者消费者模型、读者写者问题等经典...

    java sleep()和wait()

    - **线程间的通信**:在多线程环境中,通过`wait()`和`notify()`/`notifyAll()`方法可以实现线程之间的协作。 - **生产者-消费者模式**:在经典的生产者-消费者模型中,生产者生产数据,消费者消费数据。当缓冲区满...

    Java多线程机制(讲述java里面与多线程有关的函数)

    挂起线程通常通过调用`sleep()`或`wait()`方法实现,恢复线程可能通过`notify()`或`notifyAll()`唤醒,终止线程则可以通过`interrupt()`方法发送中断请求,但线程本身需要检查`isInterrupted()`或`...

    详解Java中的sleep()和wait()的区别

    在Java编程语言中,`sleep()` 和 `wait()` 都是用来控制线程执行的重要方法,但它们的作用和使用场景有着显著的区别。以下是这两个方法的详细解释: 1. **`Thread.sleep(long milliseconds)`** - `sleep()` 方法是...

    JAVA线程sleep()和wait()详解及实例

    JAVA线程sleep()和wait()详解及实例 JAVA线程sleep()和wait()是两个常用的线程控制方法,用于控制线程的执行和同步。本篇文章将详细介绍JAVA线程sleep()和wait()的原理、区别和实现机制,并提供实例代码以便更好地...

    Java多线程知识点总结

    同样,当线程使用wait方法时,它会主动释放锁并进入等待状态,直到其他线程调用notify或notifyAll方法来唤醒它。此外,sleep方法可以使线程进入阻塞状态一段时间,而join方法则允许一个线程等待另一个线程完成其任务...

    Java多线程与并发系列22道高频面试题(附思维导图和答案解析)

    本文总结了Java多线程与并发系列的22道高频面试题,涵盖了多线程的实现方法、线程停止、notify和notifyAll的区别、sleep和wait的区别、volatile关键字的作用等多方面的知识点。 一、Java中实现多线程的方法 Java中...

    Java多线程机制和线程之间的协作

    Java提供了多种机制来实现线程同步,如synchronized关键字、wait()、notify()和notifyAll()方法。这些机制用于控制线程对共享资源的访问,防止数据不一致性和死锁的发生。守护线程(Daemon Thread)是一种特殊的线程...

    Java线程中sleep和wait的区别详细介绍

    Java线程中的`sleep()`和`wait()`方法都是在多线程环境中...而`wait()`通常与`notify()`和`notifyAll()`结合使用,用于线程间的通信和协作,确保线程间的正确同步。了解这些概念有助于编写更健壮、高效的多线程应用。

    java多线程经典案例

    Java中,可以通过wait()、notify()和notifyAll()这三个Object类的方法来实现线程间的通信。这些方法必须在同步环境中使用,否则会抛出异常。此外,Java 5引入了BlockingQueue阻塞队列,它是一种线程安全的数据结构,...

    java 多线程设计模式 进程详解

    wait()、notify()和notifyAll() wait()和sleep() 线程中断 静态方法(有关同步的细节) 总结 第五章 Java线程编程的例子 数据结构和容器 简单的同步例子 一个网络服务器类 AsyncInputStream类 使用TCP...

    Java多线程通信wait()和notify()代码实例

    "Java多线程通信wait()和notify()代码实例" Java多线程通信是Java编程语言中一个重要的概念,它允许程序同时执行多个线程,以提高程序的效率和响应速度。在Java中,多线程通信主要通过wait()和notify()方法实现,...

    Java的多线程-线程间的通信.doc

    Java提供了多种机制来实现线程间的通信,包括使用wait(), notify()和notifyAll()方法,以及使用synchronized关键字控制并发访问共享资源。这些方法都定义在java.lang.Thread类中。 1. **wait(), notify()和...

Global site tag (gtag.js) - Google Analytics