`

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多线程面试题及回答(合集).docx

    `wait()`通常配合`notify()`/`notifyAll()`用于线程间的通信,`sleep()`则用于线程短暂休眠。 4) **阻塞队列实现**:`BlockingQueue`接口提供了线程安全的队列操作,如`ArrayBlockingQueue`、`LinkedBlockingQueue`...

    Java测试题2答案

    DEF A notify() B wait() C notifyAll() D sleep() E.yield() F.synchronized(this) 7.构造BufferedInputStream的合适参数是哪个? AC A BufferedInputStream B BufferedOutputStream ...

    ORACLE认证考试ocjp题库(覆盖率99%)本人刚考完

    Deadlocking can occur only when the wait(), notify(), and notifyAll() methods are used incorrectly. - 虽然这些方法的错误使用会导致死锁,但这并不是唯一的原因。 - E. It is possible for a single-...

    java笔试题大集合及答案

    - 多线程:Thread类,Runnable接口,同步机制(synchronized,wait(),notify(),notifyAll())。 - 内存管理:垃圾回收机制,堆和栈的区别,JVM内存模型。 2. **EJB方面.doc**:EJB(Enterprise JavaBeans)是...

    Java基础系列面试题(88个).pdf

    42. `notify()`唤醒一个等待的线程,`notifyAll()`唤醒所有等待的线程。 43. `run()`直接执行,`start()`创建新线程并调用`run()`。 44. 创建线程池可使用`Executors`的静态工厂方法。 45. 线程池有RUNNING、...

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

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

    SCJP 6 question demo

    - **Reversing wait() and notify():** Reversing the order of `obj.wait()` and `obj.notify()` might not cause the method to complete normally because `wait()` must be called within a synchronized block ...

    Java Thread用法 经典

    4. **线程间的通信:** 使用`wait()`、`notify()`和`notifyAll()`等方法可以在线程间进行通信。 - `wait()`:使当前线程等待直到被其他线程唤醒或超时。 - `notify()`:随机唤醒一个等待线程。 - `notifyAll()`:...

    java多线程、锁的教程跟案例

    - wait(), notify(), notifyAll():Object类的方法,用于线程间的通信,通常配合synchronized使用。 二、Java锁机制 1. **内置锁(显式锁)** - ReentrantLock(可重入锁):提供与synchronized相似的功能,但更...

    关于java经典笔记

    - 多线程:线程的创建(Thread类和Runnable接口)、同步机制(synchronized关键字,wait(),notify(),notifyAll())。 - 文件和I/O流:文件读写、缓冲流、对象序列化和反序列化。 - 网络编程:Socket编程,TCP和...

    Java大厂面试题汇总及答案解析.docx

    - 线程状态:`sleep()`方法会使线程进入可中断的等待状态,`suspend()`方法已废弃,因为它可能导致死锁,`wait()`方法会让线程进入等待锁定池,等待被`notify()`或`notifyAll()`唤醒。`yield()`方法则会让当前线程...

    Java并发编程面试题合集

    wait(), notify()和notifyAll()方法被定义在Object类中,是因为Java设计者希望所有的对象都具备等待/通知的能力,任何对象都可以作为线程间的通信机制。 Thread类的sleep()和yield()方法是静态的,因为它们操作的是...

    Java并发编程面试题(2022最新版)

    **为什么wait(), notify()和notifyAll()必须在同步方法或同步块中被调用** - 这些方法需要与锁的获取和释放配合使用,确保线程安全。 **Thread类中的yield方法的作用** - `yield()`方法让当前线程放弃CPU,让同...

    操作系统生产者与消费者问题Java简单模拟实现

    而当生产者成功放入元素或者消费者成功取出元素后,它们会调用`notify()`或`notifyAll()`来唤醒等待的线程。 总的来说,"操作系统生产者与消费者问题Java简单模拟实现"这个项目提供了一个直观的多线程编程实例,...

    零基础Java学习视频教程-从入门到精通(小白也能学会)

    线程间的同步和通信可通过synchronized关键字、wait()、notify()和notifyAll()等方法实现。 【Swing与JavaFX】 Swing和JavaFX是Java的图形用户界面(GUI)库,用于创建桌面应用。Swing是早期的选择,而JavaFX提供...

    1剑盛二面准备试题.txt1剑盛二面准备试题.txt

    42. **notify()与notifyAll()的区别**:notify()唤醒一个等待该对象锁的线程;notifyAll()唤醒所有等待该对象锁的线程。 43. **线程的run()与start()的区别**:start()用于启动线程,让线程进入就绪状态;run()是...

    java线程实例 各种小Demo

    Java提供了wait()、notify()和notifyAll()方法进行线程间的通信,但这需要在同步控制块(synchronized)中使用。Java 5引入了BlockingQueue阻塞队列,提供了一种更安全的线程间通信方式,如ArrayBlockingQueue、...

    java面试题及答案(全)

    3. **线程同步**:避免多线程环境下的数据不一致,主要方法有synchronized关键字、wait()、notify()和notifyAll()。 4. **死锁**:当两个或多个线程互相等待对方释放资源而无法继续执行时,就会发生死锁。 5. **线程...

    Java复习大纲

    - 线程同步:synchronized关键字,wait()、notify()和notifyAll()方法,以及Lock接口。 - 线程池:ExecutorService和ThreadPoolExecutor的使用,线程池的配置与优化。 9. **网络编程** - Socket编程:客户端和...

    Java中线程的等待与唤醒_动力节点Java学院整理

    这些机制在Object类中以wait(), notify()和notifyAll()方法的形式提供。这三个方法都是Java中所有对象的成员,因为它们定义在Object类中。 1. **wait()方法**: 当一个线程调用对象的wait()方法时,该线程会释放...

Global site tag (gtag.js) - Google Analytics