`

多线程之wait()&notify()

 
阅读更多

1)sleep 是线程类(Thread)的方法,导致此线程暂停执行指定时间,给执行机会给其他线程,但是监控状态依然保持,到时后会自动恢复。调用sleep 不会释放对象锁。
wait 是Object 类的方法,对此对象调用wait 方法导致本线程放弃对象锁,进入等待此对象的等待锁定池,只有针对此对象发出notify 方法(或notifyAll)后本线程才进入对象锁定池准备获得对象锁进入运行状态。

1、这两个方法来自不同的类分别是Thread和Object
2、最主要是sleep方法没有释放锁,而wait方法释放了锁,使得其他线程可以使用同步控制块或者方法。
3、wait,notify和notifyAll只能在同步控制方法或者同步控制块里面使用,而sleep可以在任何地方使用(使用范围)

  1. synchronized(x){
  2.   x.notify()
  3.   //或者wait()
  4.   }
 

4、sleep必须捕获异常,而wait,notify和notifyAll不需要捕获异常

sleep方法属于Thread类中方法,表示让一个线程进入睡眠状态,等待一定的时间之后,自动醒来进入到可运行状态,不会马上进入运行状态,因为线程调度机制恢复线程的运行也需要时间,一个线程对象调用了sleep方法之后,并不会释放他所持有的所有对象锁,所以也就不会影响其他进程对象的运行。但在sleep的过程中过程中有可能被其他对象调用它的interrupt(),产生InterruptedException异常,如果你的程序不捕获这个异常,线程就会异常终止,进入TERMINATED状态,如果你的程序捕获了这个异常,那么程序就会继续执行catch语句块(可能还有finally语句块)以及以后的代码。

注意sleep()方法是一个静态方法,也就是说他只对当前对象有效,例如t是一个线程,通过指定t.sleep()让t对象进入sleep,这样的做法是错误的,它只会是使当前线程被sleep 而不是t线程

wait属于Object的成员方法,一旦一个对象调用了wait方法,必须要采用notify()和notifyAll()方法唤醒该进程;如果线程拥有某个或某些对象的同步锁,那么在调用了wait()后,这个线程就会释放它持有的所有同步资源,而不限于这个被调用了wait()方法的对象。wait()方法也同样会在wait的过程中有可能被其他对象调用interrupt()方法而产生

 

 

2)Wait()和notify():如果条件不满足,则等待。当条件满足时,等待该条件的线程将被唤醒。一般用在synchronized机制中。

例如:线程A

   synchronized(obj) {

               while(!condition) {

                         obj.wait();

                 }

                obj.doSomething();

.....

  }

当线程A获得了obj锁后,发现条件condition不满足,无法继续下一处理,于是线程A就wait()。在另一线程B中,如果B更改了某些条件,使得线程A的condition条件满足了,就可以唤醒线程A。

线程B

      synchronized(obj) {

              condition = true;

              obj.notify();

        }

需要注意的概念是:  

   1.调用obj的wait(), notify()方法前,必须获得obj锁,也就是必须写在synchronized(obj) {……} 代码段内(或synchronized方法中)。  

   2.调用obj.wait()后,线程A就释放了obj的锁,否则线程B无法获得obj锁,也就无法在synchronized(obj) {……} 代码段内唤醒A.  

   3.当obj.wait()方法返回后,线程A需要再次获得obj锁,才能继续执行。  

   4.如果A1,A2,A3都obj.wait(),则B调用obj.notify()只能唤醒A1,A2,A3中的一个(具体哪一个由JVM决定)。  

   5.obj.notifyAll()则能全部唤醒A1,A2,A3,但是要继续执行obj.wait()的下一条语句,必须获得obj锁,因此,A1,A2,A3只有一个有机会获得锁继续执行,例如A1,其余的需要等待A1释放obj锁之后才能继续执行。

   6.当B调用obj.notify/notifyAll的时候,B正持有obj锁,因此,A1,A2,A3虽被唤醒,但是仍无法获得obj锁。直到B退出synchronized块,释放obj锁后,A1,A2,A3中的一个才有机会获得锁继续执行。

 

3)为什么wait(),notify()方法要和synchronized一起使用?

因为wait()方法是通知当前线程等待并释放对象锁,notify()方法是通知等待此对象锁的线程重新获得对象锁,然而,如果没有获得对象锁,wait方法和notify方法都是没有意义的,即必须先获得对象锁,才能对对象锁进行操作,于是,才必须把notify和wait方法写到synchronized方法或是synchronized代码块中了。

以下是demo:

public class ThreadB implements Runnable{
	
	 int total;  
	    public void run()  
	    {  
	        synchronized (this)  
	        {  
	            for (int i = 0; i < 5; i++)  //Thread-0执行完后是10
	            {  
	                total += i;  
	                System.out.println("total is " + total);  
	            }
	            if(total < 15){
	            	try {
	            		System.out.println(Thread.currentThread().getName() + "进入等待状态");
						this.wait();//Thread-0释放锁,Thread-1获取锁
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
	            } else {
	            	System.out.println(Thread.currentThread().getName() + "执行完,唤醒Thread-0继续执行");
	            	notify(); 
	            }
	            System.out.println(Thread.currentThread().getName() + "已经完成!");
	        }
	        
	    }  
	
	    public static void main(String[] args) {
		        ThreadB b = new ThreadB();  
		        Thread t1  = new Thread(b);
		        Thread t2  = new Thread(b);
		        t1.start(); 
		        t2.start(); 
		}
}

 

分享到:
评论

相关推荐

    Java多线程wait和notify

    Java多线程编程是开发高并发应用的关键技术之一,它允许程序同时执行多个任务,提高系统资源利用率。在Java中,`wait()` 和 `notify()` 方法是实现线程间通信和协作的重要工具,它们属于 `java.lang.Object` 类,这...

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

    在Java多线程编程中,wait和notify是两个非常重要的方法,它们都是Object类的方法,用于线程之间的通信和同步。下面我们将详细解释wait和notify的用法。 wait方法 wait方法是Object类的一个方法,用于让当前线程...

    浅谈java多线程wait,notify

    _java多线程wait、notify机制详解_ 在Java多线程编程中,wait和notify是两个非常重要的机制,用于实现线程之间的通信和同步。在本文中,我们将通过示例代码详细介绍Java多线程wait和notify的使用,帮助读者更好地...

    Java多线程中wait、notify、notifyAll使用详解

    Java多线程中wait、notify、notifyAll使用详解 Java中多线程编程中,wait、notify、notifyAll三个方法是非常重要的,它们都是Object对象的方法,用于线程之间的通信。下面我们将详细介绍这三个方法的使用和作用。 ...

    Java多线程通讯之wait,notify的区别详解

    Java多线程通讯之wait、notify的区别详解 Java多线程通讯是指在多线程编程中,线程之间如何进行通讯和同步的问题。其中,wait和notify是两个非常重要的方法,用于控制线程的状态和同步。 wait方法: wait方法是...

    Java 同步方式 wait和notify/notifyall

    总结一下,`wait()`, `notify()`, 和 `notifyAll()` 是Java多线程编程中的核心工具,它们与`synchronized`关键字一起,为线程间的协作提供了强大的支持。理解并熟练掌握这些概念,对于编写高效、安全的多线程程序至...

    源码—Java多线程5—死锁和wait notify notifyAll

    源码—Java多线程5—死锁和wait notify notifyAll

    主线程去控制子线程wait与notify

    在Java多线程编程中,`wait()`和`notify()`是两个非常重要的方法,它们用于线程间的协作和通信。这两个方法是Java语言中的Object类提供的,因此所有的对象都可以使用。在本文中,我们将深入探讨如何使用主线程来控制...

    wait_notify_demo

    在Java编程中,多线程是处理并发执行任务的关键技术之一。`wait()`、`notify()`和`notifyAll()`是Java中的三个关键字,它们属于Object类的方法,主要用于线程间的通信,尤其在实现生产者消费者模式时发挥着重要作用...

    41.线程间的通信-wait与notify-只唤醒一个线程或所有线程.mp4

    在学习Java过程中,自己收集了很多的Java的学习资料,分享给大家,有需要的欢迎下载,希望对大家有用,一起学习,一起进步。

    wait,notify等线程知识.pdf

    Java中的多线程协同工作是通过一系列的同步机制来实现的,其中wait、notify和notifyAll是基于对象监视器的同步原语。这些方法在Java的Object类中定义,主要用于线程间的通信和协作,确保资源的安全访问。下面将详细...

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

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

    浅谈线程通信wait,notify作用

    在多线程编程中,线程之间的通信非常重要。wait()和notify()方法是Java语言中最基本的线程通信机制。它们可以使得线程之间相互发送信号,从而实现线程之间的协作。 wait()方法的作用是使当前线程等待,暂时让出CPU...

    Java多线程同步(wait()notify()notifyAll())[文].pdf

    本文将深入探讨Java中的wait()、notify()和notifyAll()方法,以及synchronized关键字和原子操作在多线程环境中的应用。 1. **wait()方法**: - wait()是Object类的一个方法,它的作用是让当前线程暂停执行并释放它...

    Java的sychronized、wait和notify范例

    `synchronized`关键字、`wait()`和`notify()`方法是Java多线程中用于控制并发访问共享资源的重要工具,它们是Java内存模型(JMM)的一部分,主要用于解决线程间的同步问题。 一、`synchronized`关键字 `...

    java多线程之wait(),notify(),notifyAll()

    "Java多线程之wait(),notify(),notifyAll()" 在Java多线程编程中,wait(),notify(),notifyAll()是三个非常重要的方法,它们都是Object类中的方法,意味着每个对象都有这些方法。这些方法是用来实现线程之间的通信和...

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

    在Java编程语言中,多线程是...总之,理解和熟练掌握`wait()`, `notify()`以及`sleep()`的使用对于编写高效的多线程程序至关重要。在设计并发程序时,应根据需求选择合适的方法,确保线程间的协同工作和程序的正确性。

    java中几个notify、wait使用实例

    在Java的多线程编程中,`notify()`与`wait()`是实现线程间通信的重要方法,它们主要用于解决生产者消费者问题、读者写者问题等典型同步问题。这两个方法定义在`Object`类中,因此所有Java对象都可以作为锁来使用。在...

    如何在Java中正确使用 wait, notify 和 notifyAll

    wait, notify 和 notifyAll,这些在多线程中被经常用到的保留关键字,在实际开发的时候很多时候却并没有被大家重视。本文对这些关键字的使用进行了描述。  在 Java 中可以用 wait、notify 和 notifyAll 来实现...

Global site tag (gtag.js) - Google Analytics