Java基础教程——线程通信
线程通信:等待、唤醒
| Object方法 | 这些方法在拥有资源时才能调用 |
|---|---|
| notify | 唤醒某个线程。唤醒后不是立马执行,而是等CPU分配 |
| wait | 等待,释放锁,不占用CPU资源 |
| notifyAll | 唤醒全部等待的线程 |
重点:资源的有效利用

生产一个,消费一个;再生产一个,再消费一个
以热干面为例(生产者消费者问题):
class 热干面 {
int isOK = 0;
}
class 生产者 implements Runnable {
热干面 m;
public 生产者(热干面 m) {
this.m = m;
}
public void 做面() {
try {
synchronized (m) {
if (m.isOK > Desk.BUFFER_MAX) {
System.out.println("+等需要做了再做");
m.wait();
System.out.println("+开始做");
}
m.isOK++;
System.out.println("+做面" + m.isOK);
m.notify();
}
} catch (Exception e) {
e.printStackTrace();
}
}
public void run() {
while (true) {
try {
Thread.sleep(Desk.做面时间);
} catch (InterruptedException e) {
e.printStackTrace();
}
做面(); // 生产面
}
}
}
class 消费者 implements Runnable {
热干面 m;
public 消费者(热干面 m) {
this.m = m;
}
public void 吃面() {
try {
synchronized (m) {// # 锁住面对象
if (m.isOK <= 0) {
System.out.println("------等面");
m.wait();// 等待,释放锁
System.out.println("------有面了");
}
System.out.println("------吃面:" + m.isOK);
m.isOK--;
m.notify();// 唤醒另一个线程,但是,俩线程等CPU执行权
}
} catch (Exception e) {
e.printStackTrace();
}
}
public void run() {
while (true) {
try {
Thread.sleep(Desk.吃面时间);
} catch (InterruptedException e) {
e.printStackTrace();
}
吃面();
}
}
}
class Desk {// 为了管理对象、模拟现实场景,可以不要
public static final int 做面时间 = 100;
public static final int 吃面时间 = 100;
public static final int BUFFER_MAX = 1;
热干面 msg = new 热干面();
生产者 m = new 生产者(msg);
消费者 c = new 消费者(msg);
Thread t1 = new Thread(m); // 生产者线程
Thread t2 = new Thread(c); // 消费者线程
public void fn() {
t1.start();
t2.start();
}
}
public class 生产者消费者问题 {
public static void main(String[] args) {
Desk d = new Desk();
d.fn();
}
}
Java基础教程——线程通信的更多相关文章
- Java基础教程——线程局部变量
线程局部变量 ThreadLocal,线程局部变量,不提供锁,不做线程共享,而是为每个线程提供变量的独立副本. import java.util.concurrent.*; public class ...
- Java基础教程——线程同步
线程同步 synchronized:同步的 例:取钱 不做线程同步的场合,假设骗子和户主同时取钱,可能出现这种情况: [骗子]取款2000:账户余额1000 [户主]取款2000:账户余额1000 结 ...
- Java基础教程——线程池
启动新线程,需要和操作系统进行交互,成本比较高. 使用线程池可以提高性能-- 线程池会提前创建大量的空闲线程,随时待命执行线程任务.在执行完了一个任务之后,线程会回到空闲状态,等待执行下一个任务.(这 ...
- Java基础教程——线程状态
线程状态 JAVA定义了6种线程状态: Thread.State public enum State { NEW, RUNNABLE, BLOCKED, WAITING, TIMED_WAITING, ...
- Java基础教程:多线程基础(2)——线程间的通信
Java基础教程:多线程基础(2)——线程间的通信 使线程间进行通信后,系统之间的交互性会更强大,在大大提高CPU利用率的同时还会使程序员对各线程任务在处理的过程中进行有效的把控与监督. 线程间的通信 ...
- Java基础教程:多线程基础——线程池
Java基础教程:多线程基础——线程池 线程池 在正常负载的情况瞎,通过为每一个请求创建一个新的线程来提供服务,从而实现更高的响应性. new Thread(runnable).start() 在生产 ...
- Java基础教程:多线程基础(5)——倒计时器(CountDownLatch)
Java基础教程:多线程基础(5)——倒计时器(CountDownLatch) 引入倒计时器 在多线程协作完成业务功能时,有时候需要等待其他多个线程完成任务之后,主线程才能继续往下执行业务功能,在这种 ...
- Java基础教程:网络编程
Java基础教程:网络编程 基础 Socket与ServerSocket Socket又称"套接字",网络上的两个程序通过一个双向的通信连接实现数据的交换,这个连接的一端称为一个s ...
- Java基础教程:Lambda表达式
Java基础教程:Lambda表达式 本文部分内容引用自OneAPM:http://blog.oneapm.com/apm-tech/226.html 引入Lambda Java 是一流的面向对象语言 ...
随机推荐
- SpringApplication.run(xxx.class, args)背后的东东——整体脉络
从spring到springmvc,再到springboot.springcloud,应用程序api开发调用方面都已经非常熟悉,但对spring背后的扩展机制:为何一个简单的main方法可以实现这么强 ...
- 云计算管理平台之OpenStack网络服务neutron
一.简介 neutron的主要作用是在openstack中为启动虚拟机实例提供网络服务,对于neutron来讲,它可以提供两种类型的网络:第一种是provider network,这种网络就是我们常说 ...
- python获取当前时间、今天零点、235959点、昨天当前时间、明天的当前时间
python获取当前时间.今天零点.23:59:59点.昨天当前时间.明天的当前时间. 关注公众号"轻松学编程"了解更多. 获取当前时间.今天零点 使用timedalte. tim ...
- Hash 算法与 Manacher 算法
目录 前言 简单介绍 简述 Hash 冲突 离散化 基本结构 普通 Hash 简述 例题 字符串 Hash 简单介绍 核心思想 基本运算 二维字符串 Hash 例题 兔子与兔子 回文子串的最大长度 后 ...
- IT人必知,互联网主流商业模式
最近关注互联网电商营销相关方面的知识,对商业化和流量变现有了一些认知. 熟悉的朋友知道,写文章是我学习的一种方式,输出倒逼输入,继而强化知识体系,所以也把这段时间的输入,自顶向下做一个系列的分享. 对 ...
- C语言I博客作业3
这个作业属于哪个课程 <https://edu.cnblogs.com/campus/zswxy/SE2020-1 > 这个作业要求在哪里 https://edu.cnblogs.com/ ...
- Spider--实战--selenium_12306
# login12306_02 # 图像识别涉及到深度学习,这里直接将验证码识别任务发送到大佬的验证码解析地址,不过现在已经失效了,程序跑到这会报错. # 用户名和密码存储在本地工作目录中的 user ...
- JavaScript探秘:可执行的上下文堆栈
这一系列的文章,挺不错的,值得收藏细读 JavaScript探秘:可执行的上下文堆栈
- 1、线性DP 198. 打家劫舍
198. 打家劫舍 https://leetcode-cn.com/problems/house-robber/ //dp动态规划,dp[i] 状态表示0-i家的盗的得最大值.那么dp[i] = (d ...
- 字符串匹配算法之Sunday算法(转)
字符串匹配算法之Sunday算法 背景 我们第一次接触字符串匹配,想到的肯定是直接用2个循环来遍历,这样代码虽然简单,但时间复杂度却是Ω(m*n),也就是达到了字符串匹配效率的下限.于是后来人经过研究 ...