感谢博主:http://zy19982004.iteye.com/blog/1626916 这篇博文给予我线程知识很大的帮助

知识背景:(1)wait()、notify()均是Object的方法,故每个对象都拥有这2个方法。

     (2)obj.wait、obj.notify必须在synchronized(obj){}代码块内部使用

     (3)obj.wait会抛异常,obj.notify没有异常抛出

     (4)2个线程同时运行,线程1执行到obj.wait()代码时,线程阻塞,释放对象锁;线程2拿到对象锁,线程2执行到obj.notify()代码时,唤醒线程1,线程1进入锁池,此时线程2并未释放对象锁,代码继            续obj.notify()往下走,走完synchronized代码块后,线程2释放对象锁;线程2进入锁池中与线程1一起参与资源(对象锁)争抢。

     (5)下面的例子中,如果线程1(生产者)obj.notify();代码注释掉,会出现线程死锁。原因:线程2执行到obj.wait(),线程2进入等待队列中;线程1,拿到对象锁,走完代码块,因为线程2还是等待,线程1一定拿到对象锁,然后执行了obj.wait();2个线程都等待了,线程死锁。

class Info {
private String name;
private String content;
private boolean flag;
public boolean isFlag() {
return flag;
}
public void setFlag(boolean flag) {
this.flag = flag;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
}
class Producer implements Runnable {
private Info info;
public Producer(Info info) {
this.info = info;
}
@Override
public void run() {
try {
Thread.sleep(5000);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
boolean flag = false;
for (int i = 0; i < 10; i++) {
if (!flag) {
synchronized (info) {
if (info.isFlag()) {
try {
System.out.println("有产品(MLDN),生产者等待消费....");
info.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
this.info.setName("李兴华");
try {
Thread.sleep(90);
} catch (InterruptedException e) {
e.printStackTrace();
}
this.info.setContent("教学老师 + " + i);
flag = true;
info.setFlag(true);
System.out.println("set()--李兴华&&java讲师 flag="
+ info.isFlag());
info.notify();
}
} else {
synchronized (info) {
if (info.isFlag()) {
try {
System.out.println("有产品(李兴华),生产者等待消费....");
info.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
this.info.setName("MLDN");
try {
Thread.sleep(90);
} catch (InterruptedException e) {
e.printStackTrace();
}
this.info.setContent("WWW.MLDN.CN + " + i);
flag = false;
info.setFlag(true);
System.out.println("set()--MLDN&&WWW.MLDN.CN flag="
+ info.isFlag());
info.notify();
}
}
}
}
}
class Consumer implements Runnable {
private Info info;
public Consumer(Info info) {
this.info = info;
}
@Override
public void run() {
for (int i = 0; i < 10; i++) {
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (info) {
if (!info.isFlag()) {
try {
System.out.println("没有产品,等待生产....");
info.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.print(this.info.getName() + "————>");
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(this.info.getContent() + "--" + i);
info.setFlag(false);
info.notify();
}
}
}
}
public class Test_producer_consumer { public static void main(String[] args) {
Info info = new Info();
Producer p = new Producer(info);
Consumer c = new Consumer(info);
Thread t1 = new Thread(p, "p");
Thread t2 = new Thread(c, "c");
t1.start();
t2.start();
}
}

结果有上面2种,第一种,当线程1运行到obj.notify();//a处,线程2被唤醒,线程2进入竞争obj对象的锁池。线程1执行完synchronized代码块后,释放对象锁;如果线程1不再参与对象锁的竞争那么结果2中的情况不会发生;但是结果2发生了,线程1再一次拿到对象锁,然后执行到obj.wait()方法后,释放对象锁,线程1进入阻塞状态,线程2获得对象锁。

这个结果是去掉消费者Thread.sleep(5000);得到的一种结果。2个1出现说明,线程1调用obj.notify()后,线程1再一次参与了对象锁的竞争,并且获得到了。

Thread线程notify方法的自我理解的更多相关文章

  1. Thread线程join方法自我理解

    Thread线程join方法自我理解 thread.join():等待thread线程运行终止,指的是main-thread(main线程)必须等待thread线程运行结束,才能继续thread.jo ...

  2. Object类clone方法的自我理解

    网上搜帖: clone()是java.lang.Object类的protected方法,实现clone方法: 1)类自身需要实现Cloneable接口 2)需重写clone()方法,最好设置修饰符mo ...

  3. java多线程详解(6)-线程间的通信wait及notify方法

    Java多线程间的通信 本文提纲 一. 线程的几种状态 二. 线程间的相互作用 三.实例代码分析 一. 线程的几种状态 线程有四种状态,任何一个线程肯定处于这四种状态中的一种:(1). 产生(New) ...

  4. Java 多线程(七) 线程间的通信——wait及notify方法

    线程间的相互作用 线程间的相互作用:线程之间需要一些协调通信,来共同完成一件任务. Object类中相关的方法有两个notify方法和三个wait方法: http://docs.oracle.com/ ...

  5. java 之Thread线程相关yield()、sleep()、wait()、join()、run和start方法详解

    1.sleep() 使当前线程(即调用该方法的线程)暂停执行一段时间,让其他线程有机会继续执行,但它并不释放对象锁.也就是说如果有synchronized同步快,其他线程仍然不能访问共享数据.注意该方 ...

  6. (二)线程Thread中的方法详解

    1.start() start()方法的作用讲得直白点就是通知"线程规划器",此线程可以运行了,正在等待CPU调用线程对象得run()方法,产生一个异步执行的效果.通过start( ...

  7. 线程Thread中的方法详解(二)

    1.start() start()方法的作用讲得直白点就是通知"线程规划器",此线程可以运行了,正在等待CPU调用线程对象得run()方法,产生一个异步执行的效果.通过start( ...

  8. java 多线程:线程通信-等待通知机制wait和notify方法;(同步代码块synchronized和while循环相互嵌套的差异);管道通信:PipedInputStream;PipedOutputStream;PipedWriter; PipedReader

    1.等待通知机制: 等待通知机制的原理和厨师与服务员的关系很相似: 1,厨师做完一道菜的时间不确定,所以厨师将菜品放到"菜品传递台"上的时间不确定 2,服务员什么时候可以取到菜,必 ...

  9. Thread线程控制之sleep、join、setDaemon方法的用处

    Thread线程控制之sleep.join.setDaemon方法的用处 1. sleep方法 public static void sleep(long millis) throws Interru ...

随机推荐

  1. Java将string内容写入到TXT文件

    private static String filePath = "E:\\test.txt"; private static void saveAsFileWriter(Stri ...

  2. Shiro 与spring 整合的及简单使用(转)

    文章完全转载自: http://www.cnblogs.com/learnhow/p/5694876.html  ,大家可以点击访问原文链接,个人仅作学习收藏 ! 本篇内容大多总结自张开涛的<跟 ...

  3. Ctrl+Alt+Down/Up 按键冲突

    I mapped Ctrl-Alt-Up/Down to open web-browser and email client but it didn't take effect. Ctrl-Alt-U ...

  4. mysql查表的时候报错:java.sql.SQLException: Value '0000-00-00 00:00:00' can not be represented as java.sql.Timest

    在spark项目中读取mysql中的数据的时候,发生了报错: 原因:主要是因为数据库中有一些字段为null,无法进行转换: 上面字段那种,我的inserttime字段类型为timestamp类型,不为 ...

  5. ionic3 在windows环境下打包android 正式签名版APK

    生成签名文件keytool -genkey -alias demo.keystore -keyalg RSA -validity 40000 -keystore demo.keystore demo为 ...

  6. springboot killed springboot 无故停止运行解决办法

    测试环境的服务部署在阿里云服务器上,运行一段时间总是自动宕掉,在配置文件里加上内存溢出配置,也不能打印出相关日志,一直找不出原因.今天在网上:http://www.cnblogs.com/chener ...

  7. java 32个Java面试必考点

    转:https://blog.csdn.net/werqerwer 一:https://blog.csdn.net/werqerwer/article/details/88061689  Java职业 ...

  8. 【转】链接伪类(:hover)CSS背景图片有闪动BUG

    来源:http://www.css88.com/archives/744 --------------------------------------------------------------- ...

  9. JavaScript(ES6)学习笔记-Set和Map与数组和对象的比较(二)

    一.Map,Set,Array对比: 1.增 let map = new Map(); let set = new Set(); let array = []; map.set('t',1); //M ...

  10. css属性应用bug大杂烩(后续继续更新)

    一.Flex布局使用时的坑: 1.常见的左右分布的flex布局中,左侧给定宽度,右侧占满剩余空间,但当右侧中文字内容很多时,会挤占左侧空间,时左侧不能按照定宽显示. <style> .fa ...