多线程中wait、notify理解
实在惭愧,java开发多年,多线程运用一直不多,该知识点理解也不够,不怎么会用。赶上使用多线程 生产者、消费者模式,学习下该知识点。
synchronized 获取锁
wait 阻塞本线程,释放对象锁。该线程会在该代码处阻塞,不往下执行。
notify 释放对象锁,通知其他被阻塞的线程可以被唤醒。
Thread.sleep()与Object.wait()二者都可以暂停当前线程,释放CPU控制权,主要的区别在于Object.wait()在释放CPU同时,释放了对象锁的控制。
IllegalMonitorStateException异常发生是由于程序员没有注意notify(),notify(),wait()方法的使用条件,没有真正理解线程同步机制。如果当前的线程不是此对象锁的所有者,却调用该对象的notify(),notify(),wait()方法时抛出该异常。个人暂时理解为若线程没有持有任何锁,而调用这几个方法,会出现该异常。
package socket; public class Producer2 extends Thread { public class Producer extends Thread { private Share shared; private int number; public Producer(Share s, int number) { shared = s; this.number = number; } public void run() { for (int i = 0; i < 10; i++) { System.out.println("[00]"); shared.put(i); System.out.println("生产者" + this.number + " 输出的数据为:" + i); try { sleep((int) (Math.random() * 100));//这里一定要加,否则(注释掉sleep代码)消费者可能会暂时取不到cpu控制权,而没办法打印出信息。而此时消费者get()方法中已经执行notify方法,导致生产者被唤醒,继续生产执行put(),给人误导没有消费。实际已经消费而只是未打印而已。 } catch (InterruptedException e) { } System.out.println("[000]"); } } } // 共享资源对象 public class Share { private int contents; private boolean available = false; public synchronized int get() { System.out.println("[1]"); if (available == false) { try { System.out.println("[2]"); wait(); System.out.println("[3]"); } catch (InterruptedException e) { } } available = false; System.out.println("[4]"); notify();// 通知其他使用该对象的线程,你们可以在适当的时间被唤醒了。只要我锁一释放(synchronized方法体执行完),其他线程就有被唤醒的可能,就有可能把锁抢过去执行了。 System.out.println("[5]"); return contents; } public synchronized void put(int value) { System.out.println("[6]"); if (available == true) { try { System.out.println("[7]"); wait();// 我不使用该对象了,本线程睡觉了,现在是其他对象被唤醒的时机,你们可以在被wait的地方继续执行了 System.out.println("[8]"); } catch (InterruptedException e) { } } available = true; System.out.println("[9]"); notify();//这里也要加,原因是,用于唤醒其他线程,不加的话,在本线程睡觉后,消费者线程不被唤醒,生产者线程唤醒其他线程的notify方法没有机会执行,那生产者线程会一直睡大觉了。 System.out.println("[10]"); contents = value; } } // 消费者程序 public class Consumer extends Thread { private Share shared; private int number; public Consumer(Share s, int number) { shared = s; this.number = number; } public void run() { int value = 0; for (int i = 0; i < 10; i++) { System.out.println("[11]"); value = shared.get(); System.out.println("消费者" + this.number + " 得到的数据为:" + value); } } } // 主程序 public static void main(String[] args) { Producer2 test = new Producer2(); Share s = test.new Share(); Producer p = test.new Producer(s, 1); Consumer c = test.new Consumer(s, 1); p.start(); try { Thread.sleep(10); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } c.start(); } }
多线程中wait、notify理解的更多相关文章
- Java多线程中wait, notify and notifyAll的使用
本文为翻译文章,原文地址:http://www.journaldev.com/1037/java-thread-wait-notify-and-notifyall-example 在Java的Obje ...
- java多线程中wait/notify/sleep/join/yield方法以及多线程的六种状态
刚开始学线程的时候也是被这几个方法搞的云里雾里的,尤其是一开始看的毕老师的视频,老师一直在强调执行权和执行资格,看的有点懵逼,当然不是说毕老师讲的不好,就是自己有点没听明白,后来复习看了一些其他的博客 ...
- python多线程中join()的理解
在 Python 的多线程编程中,经常碰到 thread.join()这样的代码.那么今天咱们用实际代码来解释一下 join 函数的作用. 第一,当一个进程启动之后,会默认产生一个主线程,因为线程是程 ...
- 多线程中Object的wait(),notify()和Condition的wait()和singal()对锁的关联
通常将共享资源的操作放置在Sysnchronized定义的区域内,这样当其他线程也获取到这个锁时,必须的等待锁被释放时才能进入该区域.Object为任意一个对象,每个对象都存在一个标志位,并具有两个值 ...
- 多线程中的"断点"续传《notify()和wait()》
眼下在做一个项目.关于软件管理与下载的,预计项目提交日期定在6月9号.项目做了有20天了,可是在一个功能上卡住了.在这个项目中有一个功能----APK的下载须要实现. 相信大家都玩过非常多关于下载AP ...
- Java多线程中线程间的通信
一.使用while方式来实现线程之间的通信 package com.ietree.multithread.sync; import java.util.ArrayList; import java.u ...
- python 多线程中的同步锁 Lock Rlock Semaphore Event Conditio
摘要:在使用多线程的应用下,如何保证线程安全,以及线程之间的同步,或者访问共享变量等问题是十分棘手的问题,也是使用多线程下面临的问题,如果处理不好,会带来较严重的后果,使用python多线程中提供Lo ...
- Java多线程中的常用方法
本文将带你讲诉Java多线程中的常用方法 Java多线程中的常用方法有如下几个 start,run,sleep,wait,notify,notifyAll,join,isAlive,current ...
- c#语言-多线程中的锁系统(一)
介绍 平常在多线程开发中,总避免不了线程同步.本篇就对net多线程中的锁系统做个简单描述. 目录 一:lock.Monitor 1:基础. 2: 作用域. ...
- 如何在多线程中调用winform窗体控件
由于 Windows 窗体控件本质上不是线程安全的.因此如果有两个或多个线程适度操作某一控件的状态(set value),则可能会迫使该控件进入一种不一致的状态.还可能出现其他与线程相关的 bug,包 ...
随机推荐
- [原]NYOJ-大数阶乘-28
大学生程序代写 //http://acm.nyist.net/JudgeOnline/problem.php?pid=28 /*题目28题目信息运行结果本题排行讨论区大数阶乘 时间限制:3000 ms ...
- hdp 集群问题解决记录
2019-04-23 14:16:21,769 WARN namenode.FSImage (EditLogFileInputStream.java:scanEditLog(359)) - Caugh ...
- 【LeetCode】018 4Sum
题目: Given an array S of n integers, are there elements a, b, c, and d in S such that a + b + c + d = ...
- python mysql 查询返回字典结构
cur = self.conn.cursor(MySQLdb.cursors.DictCursor)加上MySQLdb.cursors.DictCursor可以返回字典结构 {列名:值} class ...
- HeartBleed bug
前两年的一个严重漏洞,影响很大.出现在openssl 1.0.1和1.0.2 beta(包含1.0.1f和1.0.2beta1).利用了TLS的heartbeat. 简单的说,该漏洞被归为缓冲过度读取 ...
- Ubuntu14.04如何用root账号登陆系统
在虚拟机VMWARE中安装完Ubuntu后,只能用新建的普通用户登陆,很不方便做实验:那如何用root用户登陆账号呢? (1)用普通账号登陆,打开终端terminal: (2)在terminal的输入 ...
- Python-Redis的List操作
Redis列表是简单的字符串列表,一个列表可以包含超过40亿个元素 lpush(name,values):在name对应的list中添加元素,每个新的元素都添加到列表的最左边 rpush(name, ...
- 全面解析JS字符串和正则表达式中的match、replace、exec等函数
转自:https://www.jb51.net/article/87730.htm 正则表达式(regular expression)描述了一种字符串匹配的模式,可以用来检查一个串是否含有某种子串.将 ...
- LAMP 1.6 Discuz打开错误
打开discuz失败, ps aux |grep mysql ps aux |grep httpd 查看mysql apache有没有打开. 重启mysql service mysqld restar ...
- HTTP返回码中301与302的区别
一.官方说法 301,302 都是HTTP状态的编码,都代表着某个URL发生了转移,不同之处在于: 301 redirect: 301 代表永久性转移(Permanently Moved). 302 ...