`
endual
  • 浏览: 3558072 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

java多线程编程基础6-notify()和notifyALL的区别

    博客分类:
  • java
 
阅读更多

多线程编程中,用于唤醒等待线程的方法有两个,一个是notify()还有一个notifyAll(),

从字面意思来看,前面一个是唤醒等待的线程,后者是唤醒所有的。

其实这是对的,我们还要指出一点的就是notify()如果没有等待的对家,用这个,是不会报错误的,notifyAll()方法也是一样的

 

 

/**
 nofify()
 线程使用notify()方法通知那些可能等等该对象的其他线程,如果有多个线程等等该对象,那么线程规划器
 任意的挑选出其中一个来发出通知,而其他线程继续保持等待的状态。如果没有任何对象等待该对象,那么notify()
 就不会起作用了。在调用notify()方法之前,线程必须获得该对象的对象级别锁,这样就具有排他性了。与
 wait()不一样的是,调用notify()不会有临时释放锁,如果调用notify()时,没有持有合适的对象锁,那么
 就抛出非法的监视器状态的锁,这个异常是运行时的异常。因此不需要try catch的结构。
 如果没有对象的wait()那么就是不起作用的

 notifyAll()
 这个方法与notify()的工作方式是一样的,但是通知的是等待该对象的线程,而不仅仅通知一个线程
 。notifyALL()的优点就是,不用去关心通知的哪个等待的线程,而是简单的通知全部就可以了。缺点就是
 如果实际上只有一个线程能够实际器作用,那么这样的通知就是一种浪费。浪费了处理器的资源了。
 如果不知道该用notifyALL还是用notify的方法,那么用notifyAll方法还保证用性能来保证程序的安全秩序
 

**/

 

 

下面我们来看下我们的实验:

 

创建4个线程,都是等待的,需要notify来唤醒他们的。

 

这个resouces类:

 

package endual;

public class Resources {

	private String name;

	public Resources() {

		this.name = "xx";
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public void wait1() {

		synchronized (this.name) {

			System.out.println("我是wait1,我将进入等待状态");

			try {
				this.name.wait();
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}

			System.out.println("我是wait1,我被唤醒了");

		}

	}

	public void wait4() {

		synchronized (this.name) {

			System.out.println("我是wait4,我将进入等待状态");

			try {
				this.name.wait();
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}

			System.out.println("我是wait4,我被唤醒了");

		}

	}

	public void wait2() {

		synchronized (this.name) {

			System.out.println("我是wait2,我将进入等待状态");

			try {
				this.name.wait();
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}

			System.out.println("我是wait2,我被唤醒了");

		}

	}

	public void wait3() {

		synchronized (this.name) {

			System.out.println("我是wait3,我将进入等待状态");

			try {
				this.name.wait();
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}

			System.out.println("我是wait3,我被唤醒了");

		}

	}
	
	public void notify1() {
		
		synchronized (this.name) {
			
			System.out.println("notify runing") ;
	
		    	name.notify() ;
			
			
			System.out.println("我已经惊醒了一次其他人,不知道是谁啊。。。");
			
		}
		
		
	}
	
	

}
 

 

 

下面是4个线程:

 

package endual;

public class Threadx1 extends Thread{

	private Resources res = null ;
	
	public Threadx1(Resources res) {
		this.res = res ;
	}
	
	public void run() {
	
		res.wait1() ;
		
	}
	
}
 

 

 

 

package endual;

public class Threadx2 extends Thread{

	private Resources res = null ;
	
	public Threadx2(Resources res) {
		this.res = res ;
	}
	
	public void run() {
	
		res.wait2() ;
		
	}
	
}
 

 

 

 

package endual;

public class Threadx3 extends Thread{

	private Resources res = null ;
	
	public Threadx3(Resources res) {
		this.res = res ;
	}
	
	public void run() {
	
		res.wait3() ;
		
	}
	
}
 

 

 

package endual;

public class Threadx4 extends Thread{

	private Resources res = null ;
	
	public Threadx4(Resources res) {
		this.res = res ;
	}
	
	public void run() {
	
		res.wait4() ;
		
	}
	
}

 

 

 

然后用一个唤醒线程来测试 notify和notifyAll的不同

 

package endual;

public class Threadx5 extends Thread{

	private Resources res = null ;
	
	public Threadx5(Resources res) {
		this.res = res ;
	}
	
	public void run() {
	
		System.out.println("我将等待下,然后执行notify");
		try {
			Thread.sleep(10000) ;
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		
		res.notify1() ;
		
	}
	
}

 

 

 

下面是测试的类

 

 

package endual;

public class CopyOfT {

	public static void main(String[] args) {
		
		Resources res = new Resources();
		Threadx1 t1 = new Threadx1(res) ;
		Threadx2 t2 = new Threadx2(res) ;
		Threadx3 t3 = new Threadx3(res) ;
		Threadx4 t4 = new Threadx4(res) ;		
		Threadx5 t5 = new Threadx5(res) ;
		
		t1.start() ;
		t2.start() ;
		t3.start() ;
		t4.start() ;
		t5.start() ;
		

	}
	
}

/**
 nofify()
 线程使用notify()方法通知那些可能等等该对象的其他线程,如果有多个线程等等该对象,那么线程规划器
 任意的挑选出其中一个来发出通知,而其他线程继续保持等待的状态。如果没有任何对象等待该对象,那么notify()
 就不会起作用了。在调用notify()方法之前,线程必须获得该对象的对象级别锁,这样就具有排他性了。与
 wait()不一样的是,调用notify()不会有临时释放锁,如果调用notify()时,没有持有合适的对象锁,那么
 就抛出非法的监视器状态的锁,这个异常是运行时的异常。因此不需要try catch的结构。
 如果没有对象的wait()那么就是不起作用的

 notifyAll()
 这个方法与notify()的工作方式是一样的,但是通知的是等待该对象的线程,而不仅仅通知一个线程
 。notifyALL()的优点就是,不用去关心通知的哪个等待的线程,而是简单的通知全部就可以了。缺点就是
 如果实际上只有一个线程能够实际器作用,那么这样的通知就是一种浪费。浪费了处理器的资源了。
 如果不知道该用notifyALL还是用notify的方法,那么用notifyAll方法还保证用性能来保证程序的安全秩序
 

**/
 

 

 

 

下面是测试的结果:

 

 

我是wait1,我将进入等待状态

我是wait2,我将进入等待状态

我是wait3,我将进入等待状态

我是wait4,我将进入等待状态

我将等待下,然后执行notify

notify runing

我已经惊醒了一次其他人,不知道是谁啊。。。

我是wait1,我被唤醒了

 

如果是notify那么唤醒的只有一个

 

 

----------------------------------------------------

 

我们将notify改成notifyAll

 

 

	public void notify1() {
		
		synchronized (this.name) {
			
			System.out.println("notify runing") ;
	
		    	name.notifyAll() ;
			
			
			System.out.println("我已经惊醒了一次其他人,不知道是谁啊。。。");
			
		}
		
		
	}
 

同样的测试:

 

我将等待下,然后执行notify
我是wait2,我将进入等待状态
我是wait4,我将进入等待状态
notify runing
我已经惊醒了一次其他人,不知道是谁啊。。。
我是wait4,我被唤醒了
我是wait2,我被唤醒了
我是wait3,我被唤醒了
我是wait1,我被唤醒了
 

全部被唤醒了。这个就是不同点了。通知的全部的等待的对象,而不仅仅是其他一个线程

 

 

分享到:
评论

相关推荐

    java 多线程编程实战指南(核心 + 设计模式 完整版)

    《Java多线程编程实战指南》这本书深入浅出地讲解了Java多线程的核心概念和实战技巧,分为核心篇和设计模式篇,旨在帮助开发者掌握并应用多线程技术。 1. **线程基础** - **线程的创建**:Java提供了两种创建线程...

    汪文君JAVA多线程编程实战(完整不加密)

    《汪文君JAVA多线程编程实战》是一本专注于Java多线程编程的实战教程,由知名讲师汪文君倾力打造。这本书旨在帮助Java开发者深入理解和熟练掌握多线程编程技术,提升软件开发的效率和质量。在Java平台中,多线程是...

    Java-jdk10-最新最全多线程编程实战指南-核心篇

    《Java-jdk10-最新最全多线程编程实战指南-核心篇》是一本深入探讨Java多线程编程的专著,针对Java 10版本进行了全面的更新和优化。这本书聚焦于Java多线程的核心概念和技术,旨在帮助开发者理解和掌握如何在并发...

    Java多线程编程

    Java多线程编程是Java开发中的重要组成部分,它允许程序同时执行多个任务,极大地提高了程序的效率和响应性。在Java中,多线程主要通过`Thread`类和并发工具来实现,接下来我们将深入探讨这些关键知识点。 1. **...

    Java多线程编程核心技术.zip

    Java多线程编程是Java开发中的重要组成部分,它允许...通过学习和实践"Java多线程编程核心技术.zip"中的内容,开发者能深入理解Java多线程的原理和应用,提升软件并发处理能力,为构建高效、稳定的应用打下坚实基础。

    java 多线程编程指南

    这份“Java多线程编程指南”深入探讨了这一主题,为中级到高级的Java开发者提供了宝贵的资源。 首先,多线程的基础概念是理解整个主题的关键。线程是程序执行的最小单元,每个线程都有自己的程序计数器、虚拟机栈、...

    java多线程编程

    Java多线程编程是Java开发中的重要组成部分,它允许程序同时执行多个任务,极大地提高了程序的效率和响应性。在Java中,多线程主要通过继承Thread类或实现Runnable接口来实现。本教程将深入探讨Java多线程的各个方面...

    Java多线程编程深入详解

    总体来看,这本书详细讲述了Java多线程编程的方方面面,从基础概念到实战应用,再到高级特性,旨在帮助读者深入理解并掌握Java多线程编程的复杂性和挑战。作者通过自己的工作经验和学习总结,为读者提供了一个全面的...

    《Java多线程编程实例》随书源码

    《Java多线程编程实例》这本书深入浅出地探讨了Java中的多线程编程,通过丰富的实例帮助读者理解和掌握这一复杂主题。随书源码提供了实际操作的机会,以便读者能够亲手实践书中的示例,加深理解。 1. **线程创建...

    Java多线程编程深入详解.docx

    在本文中,我们将深入探讨Java多线程编程的基础知识和高级技术。 什么是多进程和多线程? 在计算机科学中,进程(Process)和线程(Thread)是两种不同的概念。进程是操作系统中的一种基本执行单元,具有独立的...

    【JAVA多线程】多线程编程核心技术学习资料

    Java多线程编程是Java开发中的重要组成部分,它允许程序同时执行多个任务,极大地提高了程序的效率和响应性。在现代计算机系统中,多线程技术尤其关键,因为它们能够充分利用多核处理器的能力。这份"Java多线程编程...

    Java多线程编程实战指南核新篇&设计篇&以及和核新篇的案例代码

    《Java多线程编程实战指南》是一本深入探讨Java并发编程的书籍,涵盖了核心篇与设计模式篇。这本书旨在帮助开发者理解和掌握Java平台上的多线程编程,提升系统性能和可扩展性。在Java世界中,多线程是实现并发处理、...

    java多线程编程实例_Source

    Java多线程编程是Java开发中的重要组成部分,它允许程序同时执行多个任务,提升系统效率。在本实例源码中,包含17个章节和上百个实例,旨在深入讲解Java多线程的核心概念和实际应用。 一、线程基础知识 在Java中,...

    Java多线程编程实战指南 设计模式篇.rar

    在Java编程中,多线程是一项关键技能,它允许程序同时执行多个任务,极大地提高了程序的...通过阅读"Java多线程编程实战指南 设计模式篇.pdf",你将获得更深入的理论知识和实践技巧,为你的编程事业奠定坚实的基础。

    Java多线程知识点总结

    了解这些状态对于掌握Java多线程编程至关重要。 新建状态是指线程对象创建之后,此时线程尚未开始运行。就绪状态表示线程已经准备好运行,但CPU尚未分配时间片给它。运行状态是指线程获得CPU时间片后开始执行的过程...

    《软件开发基础(Java)》实验报告-Java多线程编程.docx

    综上所述,这个Java实验报告深入探讨了Java多线程编程的基础知识,包括线程的创建、管理、同步和互斥,以及如何在实际问题中应用这些概念,如通过多线程实现高效的排序算法。理解和熟练掌握这些技能对于Java开发者来...

    多线程精品资源--这是RedSpider社区成员原创与维护的Java多线程系列文章。.zip

    RedSpider社区的这个压缩包“多线程精品资源”显然是一个集合了社区成员原创和维护的关于Java多线程的系列文章,旨在帮助开发者深入理解和掌握多线程的核心概念及实践技巧。 1. **线程基础** - **线程的定义**:...

    java多线程编程实例.rar

    本压缩包“java多线程编程实例.rar”提供了若干个实用的小例子,旨在帮助开发者深入理解并掌握Java多线程编程的核心概念。 1. **线程基础** - **线程创建**:Java提供了两种创建线程的方式,一是通过继承`Thread`...

Global site tag (gtag.js) - Google Analytics