一、基础知识

  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. HDU 1434 幸福列车(优先队列)

    优先队列的应用 #include<iostream> #include<cstdio> #include<cstring> #include<queue> ...

  2. FZU 2107 Hua Rong Dao(暴力回溯)

    dfs暴力回溯,这个代码是我修改以后的,里面的go相当简洁,以前的暴力手打太麻烦,我也来点技术含量.. #include<iostream> #include<cstring> ...

  3. Qt5:窗口各类位置

    在Qt程序中获取窗口位置的函数有  geometry()   ,   frameGeometry()  , pos() ,x() , y()等 下面来看看这些函数的区别 还有另外两个函数 size() ...

  4. 简单三段式状态机实验3-Sequence Detect(序列检测)

    1.序列检测器的逻辑功能描述:序列检测指的就是将一个指定的序列从数字码流中识别出来.本例中,我们将设计一个"10010”序列的检测器.设x_in为数字码流输入,z_out为检出标记输出,高电 ...

  5. 阿里笔试js题

    有一个数组,其中保存的都是小写英文字符串,现在要把它按照除了第一个字母外的字符的字典顺序(字典顺序就是按首字母从a-z顺序排列,如果首字母相同则按第二个字母……)排序,请编写代码: 例:[" ...

  6. Java——异常谜题

    1.谜题36  try和finally语句,代码如下,判断输出 public class Indecisive { public static void main(String[] args) { S ...

  7. createNewFile()与createTempFile()的不同

    1, File 的 createNewFile() 方法:          createNewFile():返回值为 boolean:   方法介绍:当且仅当不存在具有此抽象路径名指定名称的文件时, ...

  8. NodeJs与ActionScript的GET和POST通讯

    今天项目遇到一个小问题,做了个小功能,向服务端发送GET请求,但是服务端解析数据是时候报语法错误,如下: make Request data error:SyntaxError: Error #113 ...

  9. Cocos2dx 3.1.1 学习笔记整理(4):事件监听与Action的初步使用

    项目忙,趁着刚才有点空,看了下触摸事件在新版本中怎么实现,遇到问题都是去:cocos2d-x-3.1.1\tests\cpp-tests\Classes下面找的,里面都是一些小例子. 首先新的CCNo ...

  10. 13款Linux运维比较实用的工具

    本文介绍几款Linux运维比较实用的工具,希望对Linux管理员有所帮助. 1.查看进程占用带宽情况-Nethogs Nethogs 是一个终端下的网络流量监控工具可以直观的显示每个进程占用的带宽. ...