`

synchronized , wait() , notify() and notifyAll()

阅读更多

 

 

   !!!!!!!!!!........................................

   这三个东西,很容易,也很容易理解,几句话就轻松搞定了。

   synchronized : 同一时刻只能有一个对象持有锁!

   wait() : 当前线程会进入阻塞状态,并放弃锁

   notify() :则会叫醒某一个线程

   notifyAll():会叫醒所有线程

 

   可是上面的理解对吗?

   至少最后两个是错的。我原以为自己掌握的还好,可是今天遇到的这些状况却让我

   不能自信的作出解释。

  

   先看synchronized:

   看下面这个例子,如果直接像下面一样通过一个SynTest对象调用,那么start这个锁就跟没加一样!

   其实这个原因很简单,加锁的对象只能在一处使用,不管你是不是加锁对象本身,t1就是那个加锁的对象,它拥有那个锁,你可以无限的

   调用它的加锁方法。

public class SynTest {	
	public static void main(String[] args) {
		SynTest t1 = new SynTest();
		for(int i = 0 ; i < 10; i++) {
			A a = t1.create();
			t1.start(a);
		}
	}
	
	A create() {
		A a  = new A();
		return a;
	}
	
	class A implements Runnable {
//		SynTest t ;
		@Override
		public void run() {
			 test();
//                       t.test(); (这里test加了synchronized) 
		}
//		A(SynTest t) {
//			this.t = t;
//		}
		
	}	
	 public void test () {
		System.out.println(this);
		try {
			Thread.sleep(10000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
	
	public  synchronized void start(Runnable a) {
		new Thread(a).start();
	}
}

 

 

    在看wait()和notify() / notifyAll() :

    这两个东西我是误区颇深啊!

    就像下面的代码,我还在一直想着,最后能够把所有的线程都唤醒了..

public class Test {

	public static void main(String[] args) throws InterruptedException {
		init();
		while(!conns.isEmpty()) {
			Conn conn = conns.remove(0);
			conn.start();
			Thread.sleep(100);
		}

	}
	
	static List<Conn> conns = new ArrayList<Conn> ();
	
	static void init() {
		conns.add(new Conn());
		conns.add(new Conn());
		conns.add(new Conn());
	}	
	static class Conn extends Thread {
		
		@Override
		public void run() {
			try {
				send();
				response();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			System.out.println(Thread.currentThread().getName() + "   get response" );
		}
		
		public synchronized void send() throws InterruptedException {
			if(!conns.isEmpty()) {
				System.out.println(Thread.currentThread().getName() + "   send  A to Server");
				wait();
			} else {
				response();
			}
		}
		
		public synchronized void response() {
			try {
				Thread.sleep(5000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			notifyAll();
		}
	}

}

 

 

    首先第一点,这两个东西必须方法在同步代码中,你可以给方法加synchronized 或者给 代码块加!

    

     然后就是notify/notifyAll  , 不是 A.notify() 或者 A.notifyAll() 就会把 B线程唤醒!!!!!

     它是与对象挂钩,那个对象notify就只能notify那些等待这个对象控制权的线程!!!!

     

如果对象调用了wait方法就会使持有该对象的线程把该对象的控制权交出去,然后处于等待状态。
如果对象调用了notify方法就会通知某个正在等待这个对象的控制权的线程可以继续运行。
如果对象调用了notifyAll方法就会通知所有等待这个对象控制权的线程继续运行。

   

   关于notify()/notifyAll()还要注意下下面这种情形:

   当调用完了notify() / notifyAll() 的时候,并不等于等待线程就会立马运行,只有等调用完notify()或者notifyAll()

  并退出synchronized块,释放对象锁后,其余线程才可获得锁执行。就像下面的例子,虽然调用了notifyAll()可是

  线程阻塞在了,只有等他醒来,等待线程才能重新获得锁。

   

synchronized (flag) {
	flag = "true";
	flag.notifyAll();
	try {
					
		Thread.sleep(10000);
	    } catch (InterruptedException e) {
		e.printStackTrace();
	    }
}

 

 

    这篇博客  : notify / notifyAll / wait

分享到:
评论

相关推荐

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

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

    【并发编程】 — 线程间的通信wait、notify、notifyAll

    文章目录1 wait、notify、notifyAll简单介绍1.1 使用方法 + 为什么不是Thread类的方法1.2 什么时候加锁、什么时候释放锁?1.3 notify、notifyAll的区别2 两个比较经典的使用案例2.1 案例1 — ABCABC。。。三个线程...

    java中的并发和多线程编程中文版

    读者将通过使用java.lang.thread类、synchronized和volatile关键字,以及wait、notify和notifyall方法,学习如何初始化、控制和协调并发操作。此外,本书还提供了有关并发编程的全方位的详细内容,例如限制和同步、...

    Java并发编程:设计原则与模式(第二版)

    读者将通过使用java.lang.thread类、synchronized和volatile关键字,以及wait、notify和notifyall方法,学习如何初始化、控制和协调并发操作。此外,本书还提供了有关并发编程的全方位的详细内容,例如限制和同步、...

    java线程学习笔记

    一 基本知识 2 1.1 任务Runnable 2 1.2 线程构造器Threat 2 1.3 执行器Executor 2 1.4 任务中返回值Callable接口 3 1.5 休眠 6 1.6 让步 6 1.7 优先级 6 1.8 后台线程(daemon) 6 ...2.5.3 notify()与notifyAll() 24

    java并发编程:线程基础

    本资源致力于向您介绍 Java 并发编程中的线程基础,涵盖了多线程编程的核心概念、线程...线程间通信: 详解线程间通信的方法,包括 wait、notify 和 notifyAll 方法的使用。讲解如何通过这些方法实现线程的协作和同步。

    高级开发并发面试题和答案.pdf

    描述一下notify和notifyAll区别; synchronized关键字加在静态方法和实例方法的区别; 用锁的注意点; cas机制可能导致的问题ABA,什么是ABA; 程序开多少线程合适; 实现一下DCL(双重检查锁) stream 和 parallel...

    java并发编程

    , 这里,读者将通过使用java.lang.thread类、synchronized和volatile关键字,以及wait、notify和notifyall方法,学习如何初始化、控制和协调并发操作。此外,本书还提供了有关并发编程的全方位的详细内容,例如限制...

    java多线程设计模式详解(PDF及源码)

    wait set——线程的休息室 wait方法——把线程放入wait set notify方法——从wait set拿出线程 notifyAll方法——从wait set拿出所有线程 wait、notify、notifyAll是Object类的方法 线程的状态移转 跟线程有关的其他...

    Java并发编程:核心理论

    本系列会从线程间协调的方式(wait、notify、notifyAll)、Synchronized及Volatile的本质入手,详细解释JDK为我们提供的每种并发工具和底层实现机制。在此基础上,我们会进一步分析java.util.concurrent包的工具类,...

    这就是标题—— JUC.pdf

    wait()、notify()和notifyAll() 虚假唤醒 Condition 定制化通信 多线程锁 并发下的集合类 List Set Map Callable接口 线程创建的方式 callable / runnable FutureTask JUC常用辅助类 CountDownLatch (减少计数器) ...

    java并发学习笔记

    文章目录1 线程基础、线程之间的共享与协作1.1 cpu时间片轮询机制1.2 进程与线程1.3 并行与并发1.4 启动线程的三种方式1.5 停止线程1.6 线程的生命周期1.7 守护线程1.8 synchronized关键字1.9 volatile关键字1.10 ...

    java笔试题大集合及答案(另附各大公司笔试题)

    wait是Object类的方法,对此对象调用wait方法导致本线程放弃对象锁,进入等待此对象的等待锁定池,只有针对此对象发出notify方法(或notifyAll)后本线程才进入对象锁定池准备获得对象锁进入运行状态。 62、同步和...

    java高并发相关知识点.docx

    Java高并发相关知识点包括: 线程:Java多线程的实现方式,包括继承Thread类和实现Runnable接口。 锁:Java中的锁机制,包括...线程间通信:Java中的线程间通信,包括wait()、notify()、notifyAll()等方法。

    多线程编程(电子书)

    Java自1995年面世以来得到了广泛得一个运用,但是对多...在Java 5.0之前Java里的多线程编程主要是通过Thread类,Runnable接口,Object对象中的wait()、 notify()、 notifyAll()等方法和synchronized关键词来实现的。

    jstack生成的Thread Dump日志.docx

    只有当别的线程在该对象上调用了 notify()或者notifyAll()方法,"Wait Set"队列中的线程才得到机会去竞争,但是只有一个线程获得对象的Monitor,恢复到运行态。"Wait Set"中的线程在Thread Dump中显示的状态为 in ...

    Practical Java(中文版(繁体+简体))

    實踐53:優先使用notifyAll()而非notify() 185 實踐54:針對wait()和notifyAll()使用旋鎖(spin locks) 187 實踐55:使用wait()和notifyAll()替換輪詢循環(polling loops) 191 實踐56:不要對locked object(㆖鎖...

    Java—线程的通信

    文章目录Java—线程的通信概念引入wait()与notify()和notifyAll()生产者和消费者模式 概念 线程通信概念:线程是操作系统中独立的个体,但这些个体如果不经过特殊处理就不能成为一个整体,线程间的通信就成为...

    生产者消费者JAVA课程设计

    notifyAll(); return contents; } public synchronized void push(char c) { while(ava==true){ try { wait(); } catch (InterruptedException e) { // TODO 自动生成 catch 块 e....

    史上最全java面试,103项重点知识,带目录

    42. notify()和 notifyAll()有什么区别? 16 43. 线程的 run()和 start()有什么区别? 16 44. 创建线程池有哪几种方式? 17 45. 线程池都有哪些状态? 18 46. 线程池中 submit()和 execute()方法有什么区别? 18 49....

Global site tag (gtag.js) - Google Analytics