一、基础知识

  java.lang.Object的类的三个方法:

    void notify():唤醒在此对象监视器上等待的单个线程。

    void notifyAll():唤醒在此对象监视器上等待的所有线程。

    void wait():导致当前线程等待,直到其他线程调用此对象的notify()方法或notifyAll()方法。

    void wait(long timeout):导致当前线程等待,直到其他线程调用此对象的notify()方法或notifyAll()方法,或者是超过指定时间。

    void wait(long timeout,int nanos):导致当前线程等待,直到其他线程调用此对象的notify()方法或notifyAll()方法,或者是其他某个线程中断当前线程,或超过某个实际时间。

以上方法使用要点:

  必须从同步环境中调用这些方法。线程不能调用对象上等待或通知的方法,除非它拥有那个对象的锁。

  以上几种方法都是Object的实例方法,与每个对象具有锁是一样的,每个对象可以有一个线程列表,它们等待来自该信号。线程通过wait()获得这个等待列表。它不再执行任何其他指令,直到调用notify()为止。如果多个线程在同一个对象上等待,则将只选择一个线程继续执行。如果没有线程等待,则不采取操作。如;

  

 package Thread;

 public class Test2 {
public static void main(String[] args){
ThreadB b=new ThreadB();
b.start();//线程A拥有b对象上的锁。线程为了调用wait()或notify()方法,该线程必须是那个对象锁的拥有者
synchronized(b){
try{
System.out.println("等待对象b完成计算...>");
b.wait();//当前线程A等待
}catch(InterruptedException e){
e.printStackTrace();
}
System.out.println("b对象计算完毕,其总和是:"+b.total);
}
}
}
class ThreadB extends Thread{
int total;
public void run(){
synchronized(this){
for(int i=0;i<101;i++){
total+=i;
}
notify();//(完成计算)唤醒在此对象监视器上等待的单个线程,在本例中A被唤醒。
}
}
}
 等待对象b完成计算...>
b对象计算完毕,其总和是:5050

  在对象上调用wait()方法时,执行该代码的线程立刻放弃它在该对象的锁,然后调用调用notify()方法,如果线程仍然在完成同步代码,则线程移出之前不会放弃锁。因此,只要调用notify()并不意味着这时的锁变得可用。

二、多个线程在等待一个对象锁时使用notifyAll()

  多数情况下,最好通知等待某个对象的所有线程。如果这样做,可以在对象上使用notifyAll()方法,让所有等待的线程返回到可运行状态。如:

 package Thread;

 public class Test2 extends Thread{
public static void main(String[] args){
Calculator calculator=new Calculator();
new Test2(calculator).start();
new Test2(calculator).start();
new Test2(calculator).start();
calculator.start();//线程A拥有b对象上的锁。线程为了调用wait()或notify()方法,该线程必须是那个对象锁的拥有者
}
Calculator calculator;
public Test2(Calculator calculator){
this.calculator=calculator;
}
public void run(){
synchronized(calculator){
try{
System.out.println(Thread.currentThread()+"等待计算结果...>");
calculator.wait();//当前线程A等待
}catch(InterruptedException e){
e.printStackTrace();
}
System.out.println(Thread.currentThread()+"结果为:"+calculator.total);
}
}
}
class Calculator extends Thread{
int total;
public void run(){
synchronized(this){
for(int i=0;i<101;i++){
total+=i;
}
notifyAll();//(完成计算)唤醒在此对象监视器上等待的单个线程,在本例中A被唤醒。
}
}
}
 Thread[Thread-1,5,main]等待计算结果...>
Thread[Thread-3,5,main]等待计算结果...>
Thread[Thread-2,5,main]等待计算结果...>
Thread[Thread-2,5,main]结果为:5050
Thread[Thread-3,5,main]结果为:5050
Thread[Thread-1,5,main]结果为:5050

Java线程:线程交互的更多相关文章

  1. Java多线程-线程的交互

    一.线程交互的基础知识void notify():唤醒在此对象监视器上等待的单个线程. void notifyAll():唤醒在此对象监视器上等待的所有线程. void wait():导致当前的线程等 ...

  2. Java的线程安全

    线程安全 我们这里讨论的线程安全,就限定于多个线程之间存在共享数据访问这个前提,因为如果一段代码根本不会与其他线程共享数据,那么从线程安全的角度来看,程序是串行执行还是多线程执行对它来说是完全没有区别 ...

  3. -1-5 java 多线程 概念 进程 线程区别联系 java创建线程方式 线程组 线程池概念 线程安全 同步 同步代码块 Lock锁 sleep()和wait()方法的区别 为什么wait(),notify(),notifyAll()等方法都定义在Object类中

     本文关键词: java 多线程 概念 进程 线程区别联系 java创建线程方式 线程组 线程池概念 线程安全 同步 同步代码块 Lock锁  sleep()和wait()方法的区别 为什么wait( ...

  4. Java WebSocket 线程安全的保证

    Java WebSocket线程安全基于3点: 1 在新的客户端连接时,WebSocket容器会创建一个新的端点实例,对应的会话实例表示从唯一的客户端到该端点实例的唯一连接. 2 每个WebSocke ...

  5. java多线程——线程池源码分析(一)

    本文首发于cdream的个人博客,点击获得更好的阅读体验! 欢迎转载,转载请注明出处. 通常应用多线程技术时,我们并不会直接创建一个线程,因为系统启动一个新线程的成本是比较高的,涉及与操作系统的交互, ...

  6. JVM之java并发 ——线程安全与锁优化

    概述 人们很难想象现实中的对象在一项工作进行期间,会被不停地中断和切换,对象的属性(数据)可能会在中断期间被修改和变“脏”,而这些事情在计算机世界中则是很正常的事情.有时候,良好的设计原则不得不向现实 ...

  7. java之线程

    java之线程 一:线程: 线程是什么呢?线程,有时被称为轻量级进程是程序执行流的最小单元.一个标准的线程由线程ID,当前指令指针(PC),寄存器集合和堆栈组成.另外,线程是进程中的一个实体,是被系统 ...

  8. Java 使用线程方式Thread和Runnable,以及Thread与Runnable的区别

    一. java中实现线程的方式有Thread和Runnable Thread: public class Thread1 extends Thread{ @Override public void r ...

  9. 深入理解Java之线程池

    原作者:海子 出处:http://www.cnblogs.com/dolphin0520/ 本文归作者海子和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则 ...

  10. java中线程分两种,守护线程和用户线程。

    java中线程分为两种类型:用户线程和守护线程. 通过Thread.setDaemon(false)设置为用户线程: 通过Thread.setDaemon(true)设置为守护线程. 如果不设置次属性 ...

随机推荐

  1. 对于crontab定时任务不能自动执行的总结

    最近遇到了一些sh不能在crontab定时任务中自动执行的问题 期间由于不太了解,故走了一点弯路,现在总结下来可能第一次 进行设置遇到的问题.以绝后患!我所用过的操作系统为HP-unix&li ...

  2. 安卓图表引擎AChartEngine(二) - 示例源码概述和分析

    首先看一下示例中类之间的关系: 1. ChartDemo这个类是整个应用程序的入口,运行之后的效果显示一个list. 2. IDemoChart接口,这个接口定义了三个方法, getName()返回值 ...

  3. javascript 中的闭包

    在 javascript 中,函数可以当做参数传递,也可以当做返回值返回. 当一个函数内部返回值为一个函数时, 就形成了闭包.(闭包里面的 this 问题) 如下面代码 Function.protot ...

  4. Mac下eclipse导入其他工程中文注释出现乱码解决方案

    因为用的是mac版的eclipse,导入其他工程注释出现乱码的情况,找了网上的很多方法,大部分都是说的workspace,在这里修改,但是我修改之后还是乱码,最后发现这样一个方法,才得以解决. 点击 ...

  5. 什么是deferred对象

    $.when().done().then()的用法  http://www.cnblogs.com/tiancai/p/5817996.html jQuery的开发速度很快,几乎每半年一个大版本,每两 ...

  6. The 2014 ACM-ICPC Asia Regional Anshan Online

    [A]无向图的双联通子图计数.DP+状态压缩 [B]计算几何(点的旋转) [C]DP+状态压缩 [D]离散数学+DP (感觉可出) [E]概率DP [F]LCT模板题(-_-///LCT是啥!!!!) ...

  7. Oracle存储过程中如何使用游标

    --本存储过程的功能:把test_tbl2中与test_tbl1中ID相同但salary不同的记录中的salary的值更新为test_tbl1中的salary的值--创建存储过程create or r ...

  8. php的命名空间层级与目录层级是一致的吗?

    php的命名空间和目录的层级之间并不是说一定 要一致,两者之间没有必然的联系.并没有直接的关联,当然了,推荐关联起来,不然管理会非常混乱,但你确实可以自己实现一个Autoload来管理“混乱”的nam ...

  9. Cocos2dx 3.1.1 将一个2.X的项目改成3.1版本

    最近在论坛上下载到了一个Cocos2dx的单机跑酷例子, 也不知道是2.x版的, 花了一天时间试着把他改成3.1.1的试试, 现在已经可以顺利编译的, 但是还是有Heap Free的问题,调试了好几天 ...

  10. Nginx 负载均衡 后端 监控检测 nginx_upstream_check_module 模块的使用

    在使用nginx 的负载均衡 中,我们通常会使用到 Nginx 自带的 ngx_http_proxy_module 健康检测模块. ngx_http_proxy_module 自带的 健康检测模块参数 ...