正在运行的程序称作一个进程,一个进程可以包含多个线程,这些线程可以共享进程的资源,它们共用一块存储空间。那么,各个线程在访问同一个数据对象的同时,可能引起冲突,以生产者、消费者为例,就会出现队列中没有产品的情况下,消费者扔到队列中去拿产品,与现实世界中逻辑不相符合。使用synchronized关键字可以确保线程的安全运行。

  synchronized(obj){
.......
  obj.wait()/notifyAll();//是数据对象而不是线程调用wait和notifyAll方法
  }

  当给一个线程(比如A线程)的run方法体内加入上述代码时,说明A线程必须首先获得该数据对象的锁,才能对这个对象进行操作。A线程拿到这个obj数据对象的锁以后,在它释放以前任何其它线程都不能够操作此对象了,之所以这样,我们可以认为其它线程没有这把锁的钥匙。A线程执行obj.wait()方法后,它将释放其所占有的对象锁,A线程进入阻塞状态,同时A也就不具有了获得obj对象所的权力,这样其它线程就可以拿到这把锁了。obj.notifyAll()可以唤醒因obj对象而阻塞的所有线程,并允许它们有获得对象所的权力,obj.notify()是唤醒因obj对象而阻塞的任意一个线程。

  下面的程序模仿生产者和消费者:  

public class WaitAndNotify {
private static List<Double> queue;
public WaitAndNotify(){
queue = new ArrayList<Double>();
} public void begin(){
Thread producer = new Thread(){
public void run(){
while(true){
synchronized(queue){
double time = 1.0d;
long startTime = System.currentTimeMillis();
if(System.currentTimeMillis()-startTime>=time){
startTime =System.currentTimeMillis();
for(int i=0;i<10;i++){
queue.add((Math.random()*10000));
}
queue.notifyAll();
}
}
}
}
};
producer.start(); Thread consumer = new Thread(){
public void run(){
while(true){
synchronized(queue){
while(queue.isEmpty()){
System.out.println("队列的长度为:"+queue.size());
try {
queue.wait();
} catch (InterruptedException ex) {
Logger.getLogger(WaitAndNotify.class.getName()).log(Level.SEVERE, null, ex);
}
}
double result = queue.remove(0);
System.out.println("成功从队列中取到数据!"+result);
}
}
}
};
consumer.start();
} public static void main(String[] args){
WaitAndNotify obj = new WaitAndNotify();
queue.add(0.1231d);
obj.begin();
}
}

  producer线程向queue中放入数据,并掉调用queue.notifyAll()来唤醒所有阻塞的线程,consumer线程从queue中取数据,当没有数据时该线程就会进入阻塞状态,等待呗唤醒。

线程以及数据对象的wait()和notifyAll()方法的更多相关文章

  1. JAVA--线程wait()、lnotify()和notifyAll()方法

    join()方法是Thread类的一个方法,而wait().notify().notifyAll()是java.lang.Object类的方法,这意味着,任何一个Java对象(包括线程对象)都有wai ...

  2. java 线程 Thread 使用介绍,包含wait(),notifyAll() 等函数使用介绍

    (原创,转载请说明出处!谢谢--http://www.cnblogs.com/linguanh/) 此文目的为了帮助大家较全面.通俗地了解线程 Thread 相关基础知识! 目录: --线程的创建: ...

  3. muduo网络库源码学习————线程特定数据

    muduo库线程特定数据源码文件为ThreadLocal.h //线程本地存储 // Use of this source code is governed by a BSD-style licens ...

  4. R语言入门(2)-数据对象

    数据对象 创建向量相关的方法 R语言的向量用法非常像python, 就比如这个seq(0,10,2), 从0到10, 步长为2, 涉及到的元素作为向量里的内容进行创建. 这里的用法非常像Matlab, ...

  5. 多线程协作wait、notify、notifyAll方法简介理解使用 多线程中篇(十四)

    在锁与监视器中有对wait和notify以及notifyAll进行了简单介绍 所有对象都有一个与之关联的锁与监视器 wait和notify以及notifyAll之所以是Object的方法就是因为任何一 ...

  6. Java线程和多线程(二)——对象中的wait,notify以及notifyAll方法

    Java对象中的wait,notify以及notifyAll方法 在Java的Object类中包含了3个final的方法,这三个方法允许线程来交流资源是否被锁定.这三个方法就是wait(),notif ...

  7. 并发编程——线程中sleep(),yield(),join(),wait(),notify(),notifyAll()区别

    前言 今天简单的讲一讲线程中sleep(),join(),yield(),wait(),notify(),notifyAll()这些方法的使用以及区别. 不过在讲这些方法之前,需要简单的介绍一下锁池和 ...

  8. Object类中wait带参方法和notifyAll方法和线程间通信

    notifyAll方法: 进入到Timed_Waiting(计时等待)状态有两种方式: 1.sleep(long m)方法,在毫秒值结束之后,线程睡醒,进入到Runnable或BLocked状态 2. ...

  9. Object类中wait代餐方法和notifyAll方法和线程间通信

    Object类中wait代餐方法和notifyAll方法 package com.yang.Test.ThreadStudy; import lombok.SneakyThrows; /** * 进入 ...

随机推荐

  1. 当html中存在url中如: onclick="toView('参数1')", 参数1是特别字符,如&asop;&quot;' "等时,浏览器解析时会报错。解决方法如文中描述

    解决方案: 自定义标签将字符串转换成unicode编码后输出显示到页面即可 解析原理:解析顺序html  ---url ----javascript---url,由于unicode编码在htm解析阶段 ...

  2. NodeJS服务器退出:完成任务,优雅退出

    上一篇文章,我们通过一个简单的例子,学习了NodeJS中对客户端的请求(request)对象的解析和处理,整个文件共享的功能已经完成.但是,纵观整个过程,还有两个地方明显需要改进: 首先,不能共享完毕 ...

  3. 引用类型之Array类型

    Array类型 ECMAScript数组与其它语言数组一样,都是数据的有序列表.但是ECMAScript数组的每一项可以保存任何类型的数据.而且,ECMAScript数组是可以动态调整的. 1.创建和 ...

  4. 使用httpclient发送post请求与get请求

    最近因为项目的要求,需要使用httpclient来发送请求.但是查阅了许多博客,大家发送请求的方法各不相同.原因是因为httpclient的jar包的不同版本,其内部方法也不相同.因此抛开具体用到的j ...

  5. will VS be going to

    1.Future - Will vs. Going to 2."Will be doing" vs. "will do" 3.Simple Future

  6. OOP—还原被遮掩的继承名称

    1.public继承——using 声明式 class Base { private: int x; public: ; virtual void mf1(int) ; virtual void mf ...

  7. java运算符新用法和^新认识

    public class Demo1 { public static void main(String[] args) { boolean t = false | true; System.out.p ...

  8. TFS遇到TF14446错误的解决方法

    先上图 使用TFS,之前遇到文件被删除直接获取最新版本就行了,今天遇到这个异常:[TF14446: 无法签出“$/****/****/**/Models.pdb”以进行编辑.您的客户端或团队项目配置为 ...

  9. L013-oldboy-mysql-dba-lesson13

    L013-oldboy-mysql-dba-lesson13 02 18:00 来自为知笔记(Wiz)

  10. Android核心组件 Service

    Service: 服务 Service 是Activity系统的核心组件之一. 因此需要继承和注册 Service 是内有界面的, 适合在后台长期的执行任务. (如放歌, 检测版本跟新, 下载, 上传 ...