!!!!!!!!!!........................................
这三个东西,很容易,也很容易理解,几句话就轻松搞定了。
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
相关推荐
需要注意的是,`wait()`, `notify()`, 和 `notifyAll()` 必须在同步上下文中(synchronized代码块或方法)调用,否则会抛出`IllegalMonitorStateException`异常。此外,调用这些方法的线程必须是拥有对象锁的线程,...
wait, notify 和 notifyAll,这些在多线程中被经常用到的保留关键字,在实际开发的时候很多时候却并没有被大家重视。本文对这些关键字的使用进行了描述。 在 Java 中可以用 wait、notify 和 notifyAll 来实现...
3. 由于 wait()、notify/notifyAll() 在synchronized 代码块执行,说明当前线程一定是获取了锁的。 4. wait() 需要被try catch包围,中断也可以使wait等待的线程唤醒。 5. notify 和wait 的顺序不能错,如果A线程先...
文章目录1 wait、notify、notifyAll简单介绍1.1 使用方法 + 为什么不是Thread类的方法1.2 什么时候加锁、什么时候释放锁?1.3 notify、notifyAll的区别2 两个比较经典的使用案例2.1 案例1 — ABCABC。。。三个线程...
标题和描述概述的知识点主要集中在Java的多线程机制中,特别是`wait`和`notify`方法在同步锁中的应用。这些方法对于控制线程之间的交互至关重要,尤其是在资源有限或需要确保数据一致性的情况下。 ### Java同步锁...
wait方法是Object类的一个方法,用于让当前线程进入等待状态,直到其他线程调用notify或notifyAll方法来唤醒它。在wait方法中,当前线程会释放它所占有的锁,并进入等待状态。wait方法可以带有参数,指定等待的时间...
Java 中Object的wait() notify() notifyAll()方法使用 在Java并发编程中,Object的wait()、notify()和notifyAll()方法是非常重要的概念,这三个方法都是Object类的方法,可以认为任意一个Object都是一种资源(或者...
Java中的`notify`和`notifyAll`是多线程编程中的关键方法,它们用于线程间的通信,特别是在处理同步机制时。这两个方法都是在`Object`类中定义的,因此可以应用于任何Java对象。 首先,我们需要理解Java的同步机制...
本文将深入探讨Java中的wait()、notify()和notifyAll()方法,以及synchronized关键字和原子操作在多线程环境中的应用。 1. **wait()方法**: - wait()是Object类的一个方法,它的作用是让当前线程暂停执行并释放它...
`wait()`、`notify()`和`notifyAll()`是Java中的三个关键字,它们属于Object类的方法,主要用于线程间的通信,尤其在实现生产者消费者模式时发挥着重要作用。本文将深入探讨这些方法以及如何在实际场景中应用它们。 ...
Java中的多线程编程是构建高效并发应用的关键技术之一,其中`wait()`、`notify()`和`notifyAll()`是Java对象锁机制中的三个关键方法,它们位于`java.lang.Object`类中,主要用于线程间通信。本文将深入探讨`notify()...
在实际应用中,我们通常使用 `synchronized` 关键字来确保对共享资源的访问是互斥的,同时保证 `wait()` 和 `notify()` 操作的正确性。下面是一个简单的例子,展示了如何通过 `wait()` 和 `notify()` 控制子线程的...
本文将深入探讨`wait`、`notify`以及`notifyAll`这三个关键字的使用及其背后的原理,帮助你理解如何在实际编程中有效地利用它们来解决线程同步问题。 首先,我们需要了解Java中的对象锁。每个Java对象都有一个内置...
当其他线程调用同一个对象的 `notify()` 或 `notifyAll()` 方法时,等待线程有机会重新获得锁并继续执行。需要注意的是,调用 `wait()` 方法必须在 `synchronized` 块或方法中进行,否则会抛出 `...
在调用wait()之前,线程必须已经获取了对象的锁,即wait()、notify()和notifyAll()都必须在`synchronized`代码块或方法中。 2. **notify()**: notify()方法用于唤醒一个正在等待同一对象监视器锁的线程。如果有多...
`synchronized`关键字、`wait()`和`notify()`方法是Java多线程中用于控制并发访问共享资源的重要工具,它们是Java内存模型(JMM)的一部分,主要用于解决线程间的同步问题。 一、`synchronized`关键字 `...
1. **锁的持有**:调用`wait()`, `notify()`, 或 `notifyAll()` 必须在同步块(`synchronized` block)或同步方法中进行,即当前线程必须持有对象的锁。否则,会抛出`IllegalMonitorStateException`异常。这是因为这些...
在深入探讨之前,我们先了解下`wait()`、`notify()`以及`notifyAll()`的基本概念。 ### `wait()` 方法 当一个线程执行到`wait()`方法时,它会释放当前持有的锁并进入等待状态,直到其他线程调用同一锁上的`notify...
首先,`wait()`, `notify()`和`notifyAll()`是Object类中的方法,它们主要用于线程间通信和协作。这些方法只能在同步环境中(如`synchronized`块或方法)使用,否则会抛出`IllegalMonitorStateException`。它们的...
* wait方法会暂停当前线程的执行,直到其他线程调用notify或notifyAll方法。 notify机制 在Java中,notify机制用于唤醒等待的线程,并重新获得锁,以便继续执行。在使用notify机制时,需要注意以下几点: * ...