1.Java多线程之wait和notify
1.首先我们来从概念上理解一下这两个方法:
(1)obj.wait(),当obj对象调用wait方法时,这个方法会让当前执行了这条语句的线程处于等待状态(或者说阻塞状态),并释放调用wait方法的对象的对象锁。
当线程执行了obj.wait()这个语句之后,这个线程处于等待状态,需要其它线程用同一个obj对象调用notify或notifyAll方法,才可能唤醒这个处于等待状态的的线程。
(2)obj.notify(), 调用这个方法,就是唤醒其它 在obj这对象锁上处于等待状态 的线程,被唤醒的线程 在得到对象锁后 就会继续执行。
概念上的文字晦涩、让人理解的不够清晰,
我们来看代码吧,
这个小程序的目的就是:启两个线程,并让这两个线程切换着执行,并按序打印ababababababababababab。
package cn.javaBase.study_thread1;
class MyRunnable implements Runnable{
private String name;
private Object obj;
public MyRunnable(String n, Object o) {
this.name = n;
this.obj = o;
}
@Override
public void run() {
synchronized (obj) {
while (true) {
System.out.println(name);
obj.notify(); //当a线程执行到这里时,它就会唤醒另一个在obj对象锁中 处于等待状态的线程
//(也就是另一个在obj对象锁中调用了obj.wait() 语句的线程)
//注意,这里它不是唤醒 所有等待线程 中的任意一个, 而是唤醒 在obj这个对象锁上处于等待状态的 线程
try {
obj.wait(); //当a线程执行到这里,它就会让 当前线程a处于等待状态,并释放obj这个对象。
System.out.println("当前线程,会阻塞在这里");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
public class Thread5AB {
public static void main(String[] args) throws InterruptedException {
//这个程序中 共同的锁对象
Object o = new Object();
MyRunnable r1 = new MyRunnable("a", o);
MyRunnable r2 = new MyRunnable("b", o);
Thread th1 = new Thread(r1);
Thread th2 = new Thread(r2);
th1.start();
Thread.sleep(500); //这个是保证打印a的线程先启动
th2.start();
}
}
为了描述方便, 假设 上面的th1 和th2 分别代表着a、b线程
对于这个程序,重点应该是理解39、40行,r1和r2构造时,会什么传递的是同一个Object 类型的o对象,
因为:当a线程执行到22行时,a线程就处于等待状态,这时候b线程执行,当b线程直线到18行时,b线程就可以唤醒阻塞在o对象锁上的线程,而此时a线程不就是那个阻塞在o对象锁上的线程吗,
所以等b线程执行到18行时,a线程就被唤醒(但是这个时候a线程还不能进入synchronized代码块,就是这个对象锁中,因为进入这个代码块,需要有obj这个对象,obj这个对象就像是进入这个代码块的钥匙),
接下来等到b线程执行到22行时,b线程就把obj这个对象释放了,自己进入等待状态,此时a线程已经处于唤醒了的状态,并可以得到obj这个对象,所以接下来a线程就可以继续执行synchronized代码块中的内容,
这就是a、b线程第一次切换执行的过程,后面就依次这样循环执行,

控制台就打印了我们想要的结果ababababab...
重要的问题是,你要知道obj.notify()执行时,唤醒的是那个处于等待的线程,它唤醒的是在obj这个对象锁上处于等待的线程。
不知道这样解释的是否还可以,本人也是最近稿明白,
1.Java多线程之wait和notify的更多相关文章
- java多线程之wait和notify协作,生产者和消费者
这篇直接贴代码了 package cn.javaBase.study_thread1; class Source { public static int num = 0; //假设这是馒头的数量 } ...
- Java多线程之Wait()和Notify()
1.Wait()和Notify.NotifyAll都是Object的方法 2.多线程的协作是通过控制同一个对象的Wait()和Notify()完成 3.当调用Wait()方法时,当前线程进入阻塞状态, ...
- Java多线程之wait、notify/notifyAll 详解,用wait 和notifyAll 以及synchronized实现阻塞队列,多线程拓展之ReentrantLock与Condition
前言:这几天看了很多关于多线程的知识,分享一波.(但是目前接触的项目还未用到过,最多用过线程池,想看线程池 请看我之前的博客) 关于基本的理论等 参考如下: https://www.cnblogs.c ...
- java多线程之wait和notify
多线程中的通信是非常重要的概念,线程直接实现通信就可以并发完成很多复杂工作. java在Object类中就设计了wait()和notify()两个方法,以解决这个问题. 1.释义: wait()方法将 ...
- java 多线程之synchronized wait/notify解决买票问题
一.Java线程具有五中基本状态 新建状态(New):当线程对象对创建后,即进入了新建状态,如:Thread t = new MyThread(); 就绪状态(Runnable):当调用线程对象的st ...
- JAVA多线程之wait/notify
本文主要学习JAVA多线程中的 wait()方法 与 notify()/notifyAll()方法的用法. ①wait() 与 notify/notifyAll 方法必须在同步代码块中使用 ②wait ...
- JAVA多线程之volatile 与 synchronized 的比较
一,volatile关键字的可见性 要想理解volatile关键字,得先了解下JAVA的内存模型,Java内存模型的抽象示意图如下: 从图中可以看出: ①每个线程都有一个自己的本地内存空间--线程栈空 ...
- java多线程之yield,join,wait,sleep的区别
Java多线程之yield,join,wait,sleep的区别 Java多线程中,经常会遇到yield,join,wait和sleep方法.容易混淆他们的功能及作用.自己仔细研究了下,他们主要的区别 ...
- Java多线程之ConcurrentSkipListMap深入分析(转)
Java多线程之ConcurrentSkipListMap深入分析 一.前言 concurrentHashMap与ConcurrentSkipListMap性能测试 在4线程1.6万数据的条件下, ...
随机推荐
- 剑指offer-面试题16-数值的整数次方-数字
/* 题目: 实现函数double Power(double base,int exponent), 求base的exponent次方. */ /* 思路: 本题需要考虑的情况较多: 1.0的负数次方 ...
- 剑指offer-面试题9-用两个栈实现队列-栈和队列
/* 题目: 用两个栈实现一个队列.队列声明如下. */ /* 思路: 将值压入stack1,再从stack1弹出到stack2,则为先进先出. appendTail时直接压入stack1即可,当st ...
- 查看whl包名是否满足系统的条件的命令,以此解决whl包出现“is not a supported wheel on this platform”错误提示的问题
在Ubuntu系统中,使用pip安装whl包时,常常会报如下错误: tensorflow_gpu-1.11.0-cp35-cp35m-manylinux1_x86_64.whl is not a su ...
- C#常规TcpListener
1.Xaml <Window x:Class="Server.MainWindow" xmlns="http://schemas.microsoft.com/win ...
- 51Nod 1091 线段的重叠 (贪心)
X轴上有N条线段,每条线段包括1个起点和终点.线段的重叠是这样来算的,[10 20]和[12 25]的重叠部分为[12 20]. 给出N条线段的起点和终点,从中选出2条线段,这两条线段的重叠部分是最长 ...
- (转) 统计在从1到n的正整数中1出现的次数
1. 题目描述 输入一个整数n,求从1到n这n个整数的十进制表示中1出现的次数.例如输入12,从1到12这些整数中包含1的数字有1,10,11和12,1一共出现了5次. 2. 题目来源 第一次看到是在 ...
- redis 有序集合(set),无需集合(zset)
1.set(无序集合)无序集合每个元素都是string元素的唯一性,不能重复没有修改操作 1.增加 sadd key value1 value2 value3... 2.获取 smembers key ...
- gz、tar、zip、bz2压缩和解压缩命令
gzip 压缩后的格式为:*.gz 这种压缩方式不能保存原文件:且不能压缩目录 命令举例:#压缩[root@localhost tmp]# gzip buodo[root@localhost tmp] ...
- <if test="type == '0' ">没有进去这个判断的问题
在MyBatis的mapp文件中的if判断中是这样写的 <if test="type == '0' "> and so1.id = #{unitcode} </i ...
- opencv:程序运行完保持dos窗口不关闭
(1)在main函数最后加上 system("pause"); 第一种不能加到含有imshow图片显示的结尾:否则会不能显示图片: (2)利用cvWaitKey()函数: 这种能加 ...