!!!!!!!!!!........................................
这三个东西,很容易,也很容易理解,几句话就轻松搞定了。
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,这些在多线程中被经常用到的保留关键字,在实际开发的时候很多时候却并没有被大家重视。本文对这些关键字的使用进行了描述。 在 Java 中可以用 wait、notify 和 notifyAll 来实现...
文章目录1 wait、notify、notifyAll简单介绍1.1 使用方法 + 为什么不是Thread类的方法1.2 什么时候加锁、什么时候释放锁?1.3 notify、notifyAll的区别2 两个比较经典的使用案例2.1 案例1 — ABCABC。。。三个线程...
读者将通过使用java.lang.thread类、synchronized和volatile关键字,以及wait、notify和notifyall方法,学习如何初始化、控制和协调并发操作。此外,本书还提供了有关并发编程的全方位的详细内容,例如限制和同步、...
读者将通过使用java.lang.thread类、synchronized和volatile关键字,以及wait、notify和notifyall方法,学习如何初始化、控制和协调并发操作。此外,本书还提供了有关并发编程的全方位的详细内容,例如限制和同步、...
一 基本知识 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 并发编程中的线程基础,涵盖了多线程编程的核心概念、线程...线程间通信: 详解线程间通信的方法,包括 wait、notify 和 notifyAll 方法的使用。讲解如何通过这些方法实现线程的协作和同步。
描述一下notify和notifyAll区别; synchronized关键字加在静态方法和实例方法的区别; 用锁的注意点; cas机制可能导致的问题ABA,什么是ABA; 程序开多少线程合适; 实现一下DCL(双重检查锁) stream 和 parallel...
, 这里,读者将通过使用java.lang.thread类、synchronized和volatile关键字,以及wait、notify和notifyall方法,学习如何初始化、控制和协调并发操作。此外,本书还提供了有关并发编程的全方位的详细内容,例如限制...
wait set——线程的休息室 wait方法——把线程放入wait set notify方法——从wait set拿出线程 notifyAll方法——从wait set拿出所有线程 wait、notify、notifyAll是Object类的方法 线程的状态移转 跟线程有关的其他...
本系列会从线程间协调的方式(wait、notify、notifyAll)、Synchronized及Volatile的本质入手,详细解释JDK为我们提供的每种并发工具和底层实现机制。在此基础上,我们会进一步分析java.util.concurrent包的工具类,...
wait()、notify()和notifyAll() 虚假唤醒 Condition 定制化通信 多线程锁 并发下的集合类 List Set Map Callable接口 线程创建的方式 callable / runnable FutureTask JUC常用辅助类 CountDownLatch (减少计数器) ...
文章目录1 线程基础、线程之间的共享与协作1.1 cpu时间片轮询机制1.2 进程与线程1.3 并行与并发1.4 启动线程的三种方式1.5 停止线程1.6 线程的生命周期1.7 守护线程1.8 synchronized关键字1.9 volatile关键字1.10 ...
wait是Object类的方法,对此对象调用wait方法导致本线程放弃对象锁,进入等待此对象的等待锁定池,只有针对此对象发出notify方法(或notifyAll)后本线程才进入对象锁定池准备获得对象锁进入运行状态。 62、同步和...
Java高并发相关知识点包括: 线程:Java多线程的实现方式,包括继承Thread类和实现Runnable接口。 锁:Java中的锁机制,包括...线程间通信:Java中的线程间通信,包括wait()、notify()、notifyAll()等方法。
Java自1995年面世以来得到了广泛得一个运用,但是对多...在Java 5.0之前Java里的多线程编程主要是通过Thread类,Runnable接口,Object对象中的wait()、 notify()、 notifyAll()等方法和synchronized关键词来实现的。
只有当别的线程在该对象上调用了 notify()或者notifyAll()方法,"Wait Set"队列中的线程才得到机会去竞争,但是只有一个线程获得对象的Monitor,恢复到运行态。"Wait Set"中的线程在Thread Dump中显示的状态为 in ...
實踐53:優先使用notifyAll()而非notify() 185 實踐54:針對wait()和notifyAll()使用旋鎖(spin locks) 187 實踐55:使用wait()和notifyAll()替換輪詢循環(polling loops) 191 實踐56:不要對locked object(㆖鎖...
文章目录Java—线程的通信概念引入wait()与notify()和notifyAll()生产者和消费者模式 概念 线程通信概念:线程是操作系统中独立的个体,但这些个体如果不经过特殊处理就不能成为一个整体,线程间的通信就成为...
notifyAll(); return contents; } public synchronized void push(char c) { while(ava==true){ try { wait(); } catch (InterruptedException e) { // TODO 自动生成 catch 块 e....
42. notify()和 notifyAll()有什么区别? 16 43. 线程的 run()和 start()有什么区别? 16 44. 创建线程池有哪几种方式? 17 45. 线程池都有哪些状态? 18 46. 线程池中 submit()和 execute()方法有什么区别? 18 49....