`

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()` 必须在同步上下文中(synchronized代码块或方法)调用,否则会抛出`IllegalMonitorStateException`异常。此外,调用这些方法的线程必须是拥有对象锁的线程,...

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

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

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

    3. 由于 wait()、notify/notifyAll() 在synchronized 代码块执行,说明当前线程一定是获取了锁的。 4. wait() 需要被try catch包围,中断也可以使wait等待的线程唤醒。 5. notify 和wait 的顺序不能错,如果A线程先...

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

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

    Java 同步锁 wait notify 学习心得

    标题和描述概述的知识点主要集中在Java的多线程机制中,特别是`wait`和`notify`方法在同步锁中的应用。这些方法对于控制线程之间的交互至关重要,尤其是在资源有限或需要确保数据一致性的情况下。 ### Java同步锁...

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

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

    Java 中Object的wait() notify() notifyAll()方法使用

    Java 中Object的wait() notify() notifyAll()方法使用 在Java并发编程中,Object的wait()、notify()和notifyAll()方法是非常重要的概念,这三个方法都是Object类的方法,可以认为任意一个Object都是一种资源(或者...

    Java notify和notifyAll的区别和相同

    Java中的`notify`和`notifyAll`是多线程编程中的关键方法,它们用于线程间的通信,特别是在处理同步机制时。这两个方法都是在`Object`类中定义的,因此可以应用于任何Java对象。 首先,我们需要理解Java的同步机制...

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

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

    wait_notify_demo

    `wait()`、`notify()`和`notifyAll()`是Java中的三个关键字,它们属于Object类的方法,主要用于线程间的通信,尤其在实现生产者消费者模式时发挥着重要作用。本文将深入探讨这些方法以及如何在实际场景中应用它们。 ...

    基于Java多线程notify与notifyall的区别分析

    Java中的多线程编程是构建高效并发应用的关键技术之一,其中`wait()`、`notify()`和`notifyAll()`是Java对象锁机制中的三个关键方法,它们位于`java.lang.Object`类中,主要用于线程间通信。本文将深入探讨`notify()...

    Java多线程wait和notify

    在实际应用中,我们通常使用 `synchronized` 关键字来确保对共享资源的访问是互斥的,同时保证 `wait()` 和 `notify()` 操作的正确性。下面是一个简单的例子,展示了如何通过 `wait()` 和 `notify()` 控制子线程的...

    等待机制与锁机制wait notify

    本文将深入探讨`wait`、`notify`以及`notifyAll`这三个关键字的使用及其背后的原理,帮助你理解如何在实际编程中有效地利用它们来解决线程同步问题。 首先,我们需要了解Java中的对象锁。每个Java对象都有一个内置...

    wait和notifyAll方法的使用示例

    当其他线程调用同一个对象的 `notify()` 或 `notifyAll()` 方法时,等待线程有机会重新获得锁并继续执行。需要注意的是,调用 `wait()` 方法必须在 `synchronized` 块或方法中进行,否则会抛出 `...

    wait,notify等线程知识.pdf

    在调用wait()之前,线程必须已经获取了对象的锁,即wait()、notify()和notifyAll()都必须在`synchronized`代码块或方法中。 2. **notify()**: notify()方法用于唤醒一个正在等待同一对象监视器锁的线程。如果有多...

    Java的sychronized、wait和notify范例

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

    Java的wait(), notify()和notifyAll()使用心得

    1. **锁的持有**:调用`wait()`, `notify()`, 或 `notifyAll()` 必须在同步块(`synchronized` block)或同步方法中进行,即当前线程必须持有对象的锁。否则,会抛出`IllegalMonitorStateException`异常。这是因为这些...

    java中几个notify、wait使用实例

    在深入探讨之前,我们先了解下`wait()`、`notify()`以及`notifyAll()`的基本概念。 ### `wait()` 方法 当一个线程执行到`wait()`方法时,它会释放当前持有的锁并进入等待状态,直到其他线程调用同一锁上的`notify...

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

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

    浅谈java多线程wait,notify

    * wait方法会暂停当前线程的执行,直到其他线程调用notify或notifyAll方法。 notify机制 在Java中,notify机制用于唤醒等待的线程,并重新获得锁,以便继续执行。在使用notify机制时,需要注意以下几点: * ...

Global site tag (gtag.js) - Google Analytics