Java多线程-线程的交互
一、线程交互的基础知识
void notify():唤醒在此对象监视器上等待的单个线程。
void notifyAll():唤醒在此对象监视器上等待的所有线程。
void wait():导致当前的线程等待,直到其他线程调用此对象的 notify()方法或 notifyAll()方法。
当然,wait()还有另外两个重载方法:
void wait(long timeout):导致当前的线程等待,直到其他线程调用此对象的 notify()方法或 notifyAll()方法,或者超过指定的时间量。
void wait(long timeout, int nanos):导致当前的线程等待,直到其他线程调用此对象的 notify()方法或 notifyAll()方法,或者其他某个线程中断当前线程,或者已超过某个实际时间量。
关于等待/通知,要记住的关键点是:
必须从同步代码块内调用wait()、notify()、notifyAll()方法。线程不能调用对象上等待或通知的方法,除非它拥有那个对象的锁。
wait()、notify()、notifyAll()都是Object的实例方法。与每个对象具有锁一样,每个对象可以有一个线程列表,他们等待来自该信号(通知)。线程通过执行对象上的wait()方法获得这个等待列表。从那时候起,它不再执行任何其他指令,直到调用对象的notify()方法为止。如果多个线程在同一个对象上等待,则将只选择一个线程(不保证以何种顺序)继续执行。如果没有线程等待,则不采取任何特殊操作。
例子
package cn.thread; /**
* 计算1+2+3 ... +100的和
*
* @author 林计钦
* @version 1.0 2013-7-23 上午10:06:04
*/
public class ThreadSum extends Thread {
int total = 0; @Override
public void run() { synchronized (this) {
for (int i = 0; i < 101; i++) {
total += i;
}
//(完成计算了)唤醒在此对象监视器上等待的单个线程,在本例中线程ThreadInteractionTest被唤醒
notify();
} }
}
package cn.thread; /**
* 线程的交互
*
* @author 林计钦
* @version 1.0 2013-7-23 上午10:04:11
*/
public class ThreadInteractionTest {
public static void main(String[] args) { ThreadSum sum = new ThreadSum();
// 启动计算线程
sum.start();
// 线程ThreadInteractionTest拥有sum对象上的锁。
// 线程为了调用wait()或notify()方法,该线程ThreadInteractionTest必须是那个对象锁的拥有者
synchronized (sum) {
try {
System.out.println("等待对象sum完成计算。。。");
// 当前线程ThreadInteractionTest等待
sum.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("sum对象计算的总和是:" + sum.total);
} }
}
等待对象sum完成计算。。。
sum对象计算的总和是:5050
注意:当在对象上调用wait()方法时,执行该代码的线程立即放弃它在对象上的锁。然而调用notify()时,并不意味着这时线程会放弃其锁。如果线程仍然在完成同步代码,则线程在移出之前不会放弃锁。因此,只要调用notify()并不意味着这时该锁变得可用。
二、多个线程在等待一个对象锁时使用notifyAll()
在多数情况下,最好通知等待某个对象的所有线程。如果这样做,可以在对象上使用notifyAll()让所有在此对象上等待的线程冲出等待区,返回到可运行状态。
package cn.thread; /**
* 计算1+2+3 ... +100的和
*
* @author 林计钦
* @version 1.0 2013-7-23 上午10:06:04
*/
public class ThreadSum2 extends Thread {
int total = 0; @Override
public void run() { synchronized (this) {
for (int i = 0; i < 101; i++) {
total += i;
}
//通知所有在此对象上等待的线程
notifyAll();
} }
}
package cn.thread; /**
* 线程的交互
*
* @author 林计钦
* @version 1.0 2013-7-23 上午10:04:11
*/
public class ThreadInteractionTest2 extends Thread{
ThreadSum2 sum; public ThreadInteractionTest2(ThreadSum2 sum){
this.sum=sum;
} @Override
public void run() {
synchronized (sum) {
try {
System.out.println("等待对象sum完成计算。。。");
// 当前线程ThreadInteractionTest等待
sum.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("sum对象计算的总和是:" + sum.total);
}
} public static void main(String[] args) {
ThreadSum2 sum = new ThreadSum2(); //启动三个线程,分别获取计算结果
new ThreadInteractionTest2(sum).start();
new ThreadInteractionTest2(sum).start();
new ThreadInteractionTest2(sum).start(); // 启动计算线程
sum.start(); }
}
等待对象sum完成计算。。。
等待对象sum完成计算。。。
等待对象sum完成计算。。。
sum对象计算的总和是:5050
sum对象计算的总和是:5050
sum对象计算的总和是:5050
谈一下synchronized和wait()、notify()等的关系:
1、有synchronized的地方不一定有wait,notify
2、有wait,notify的地方必有synchronized.这是因为wait和notify不是属于线程类,而是每一个对象都具有的方法,而且,这两个方法都和对象锁有关,有锁的地方,必有synchronized。
另外,注意一点:如果要把notify和wait方法放在一起用的话,必须先调用notify后调用wait,因为如果调用完wait,该线程就已经不是currentthread了。
Java多线程-线程的交互的更多相关文章
- java 多线程—— 线程让步
java 多线程 目录: Java 多线程——基础知识 Java 多线程 —— synchronized关键字 java 多线程——一个定时调度的例子 java 多线程——quartz 定时调度的例子 ...
- java 多线程—— 线程等待与唤醒
java 多线程 目录: Java 多线程——基础知识 Java 多线程 —— synchronized关键字 java 多线程——一个定时调度的例子 java 多线程——quartz 定时调度的例子 ...
- Java多线程--线程及相关的Java API
Java多线程--线程及相关的Java API 线程与进程 进程是线程的容器,程序是指令.数据的组织形式,进程是程序的实体. 一个进程中可以容纳若干个线程,线程是轻量级的进程,是程序执行的最小单位.我 ...
- Java多线程-线程的同步(同步方法)
线程的同步是保证多线程安全访问竞争资源的一种手段.线程的同步是Java多线程编程的难点,往往开发者搞不清楚什么是竞争资源.什么时候需要考虑同步,怎么同步等等问题,当然,这些问题没有很明确的答案,但有些 ...
- Java多线程——线程的优先级和生命周期
Java多线程——线程的优先级和生命周期 摘要:本文主要介绍了线程的优先级以及线程有哪些生命周期. 部分内容来自以下博客: https://www.cnblogs.com/sunddenly/p/41 ...
- Java多线程——线程的创建方式
Java多线程——线程的创建方式 摘要:本文主要学习了线程的创建方式,线程的常用属性和方法,以及线程的几个基本状态. 部分内容来自以下博客: https://www.cnblogs.com/dolph ...
- Java多线程——线程之间的协作
Java多线程——线程之间的协作 摘要:本文主要学习多线程之间是如何协作的,以及如何使用wait()方法与notify()/notifyAll()方法. 部分内容来自以下博客: https://www ...
- Java多线程——线程的死锁
Java多线程——线程的死锁 摘要:本文主要介绍了Java多线程中遇到的死锁问题. 部分内容来自以下博客: https://www.cnblogs.com/wy697495/p/9757982.htm ...
- Java多线程——线程之间的同步
Java多线程——线程之间的同步 摘要:本文主要学习多线程之间是如何同步的,如何使用volatile关键字,如何使用synchronized修饰的同步代码块和同步方法解决线程安全问题. 部分内容来自以 ...
随机推荐
- Ubuntu16.04配置apache+php+mysql
命令行配置apache input sudo apt-get install apache2 done! 命令行配置mysql 参见: MySQL install and setting 命令行配置p ...
- 微软SaaS多租户解决方案
微软SaaS多租户解决方案 docs.microsoft.com/en-us/azure/sql-database/saas-tenancy-app-design-patterns https://d ...
- SCARA——OpenGL入门学习五六(三维变换、动画)
OpenGL入门学习(五) 此课为三维变换的内容,比较枯燥.主要是因为很多函数在单独使用时都不好描述其效果, 在前面绘制几何图形的时候,大家是否觉得我们绘图的范围太狭隘了呢?坐标只能从-1到1,还只能 ...
- UVA12296 Pieces and Discs
题意 PDF 分析 可以看成直线切割多边形,直接维护. 对每个多边形考虑每条边和每个点即可. 时间复杂度?不过\(n,m \leq 20\)这种数据怎么都过了.据说是\(O(n^3)\)的,而且常数也 ...
- Jam的计数法
Jam的计数法 题目描述 Description Jam是个喜欢标新立异的科学怪人.他不使用阿拉伯数字计数,而是使用小写英文字母计数,他觉得这样做,会使世界更加丰富多彩.在他的计数法中,每个数字的位数 ...
- vue-cli结构
|-- build // 项目构建(webpack)相关代码 | |-- build.js // 生产环境构建代码 | |-- check-version.js // 检查node.npm等版本 | ...
- (转)setTextColor()的参数设置方式
setTextColor()的参数设置方式 分类: Android界面研究2011-12-09 23:27 11160人阅读 评论(2) 收藏 举报 查了下资料发现setTextColor()的参数应 ...
- spring切面配置,代理用jdk和cglib的区别
jdk的动态代理大家应该都听说过,条件是必须要有接口:cglib不要求接口,那么它是怎么实现切面的呢?很简单,通过继承,它动态的创建出一个目标类的子类,复写父类的方法,由此实现对方法的增强.看例子: ...
- mysql中修改密码的方式
参考地址:https://www.cnblogs.com/yang82/p/7794712.html mysql中修改用户密码的方式: 最简单的方法就是借助第三方工具Navicat for MySQL ...
- c#winform图表控件使用示例
公司有个需求,需要做嵌入式开发,跟硬件通信,把数据实时展示到winform中,网上查了资料,先写下个demo备用,到时候接入socket通信就完成了,具体效果如图 实现的原理是把最开始的数据去掉,加入 ...