一、等待与通知

public final void wait() throws InterruptedException

     等待条件的发生。

public final void wait(long timeout) throws InterruptedException

     等待条件的发生。假设通知没有在timeout指定的时间内发生,它还是会返回。
public final void wait(long timeout, int nanos) throws InterruptedException
     等待条件的发生。

假设通知没有在timeout指定的毫秒与纳秒内发生。它还是会返回。


public final void notify()

     通知正在等待的Thread此条件已经发生。

public final void notifyAll()
     通知全部正在等待的Thread此条件已经发生。

    等待-通知机制的目的为何?它是怎样运作的? 
     等待-通知机制是同步机制。它更是一个通信机制:它可以让某个Thread与其它Thread在特定条件符合时进行通信。等待-通知机制并没有指定特定条件是什么。
    等待-通知机制可以用来代替synchronized机制吗?
     不行。wait、notify、notifyAll方法方法必须从synchronized方法块中调用,由于须要其确保等待与通知的线程安全不会出现竞态条件。

public class AnimatedCharacterDisplayCanvas extends CharacterDisplayCanvas implements CharacterListener, Runnable {

    private boolean done = true;
private int curX = 0;
private Thread timer = null; public AnimatedCharacterDisplayCanvas() {
} public AnimatedCharacterDisplayCanvas(CharacterSource cs) {
super(cs);
} public synchronized void newCharacter(CharacterEvent ce) {
curX = 0;
tmpChar[0] = (char) ce.character;
repaint();
} protected synchronized void paintComponent(Graphics gc) {
Dimension d = getSize();
gc.clearRect(0, 0, d.width, d.height);
if (tmpChar[0] == 0)
return;
int charWidth = fm.charWidth(tmpChar[0]);
gc.drawChars(tmpChar, 0, 1,
curX++, fontHeight);
} public synchronized void run() {
while (true) {
try {
if (done) {
wait();
} else {
repaint();
wait(100);
}
} catch (InterruptedException ie) {
return;
}
}
} public synchronized void setDone(boolean b) {
done = b; if (timer == null) {
timer = new Thread(this);
timer.start();
}
if (!done)
notify();
}
}

     sleep与wait方法的差别?
     wait与notify方法都必须在同步方法中。在一个类中的两个同步方法使用的都是当前this作为锁,wait方法运行后会释放掉当前方法锁。由于假设不释放的话notify永远无法获取到此锁,也就永远无法运行notify。
     sleep方法是不会释放锁的,而且堵塞当前线程,一直到sleep指定的时间结束。

等待-通知机制与同步
存在于等待-通知机制中的竞态条件细节是什么?
1. 第一个Thread測试条件并确认它须要等待
2. 第二个Thread设定此条件
3. 第二个Thread调用notify方法,这不会被收到。由于第二个Thread还没有进入等待
4. 第一个Thread调用wait方法

这个潜在的竞态条件状况是怎样解决的? 
     调用wait与调用notify的方法都使用同一锁(当前对象this)。由锁来保证操作的原子性。

假设Thread收到通知,是否可以保证条件被正确的设定?
     不是。描写叙述情景

wait(), notify() 与 notifyAll()
当一个以上的Thread在等待通知时哪个Thread会在调用notify的时候收到通知?
     Java规范未定义哪一个Thread收到通知。

可是Object class 提供另外一个方法notifyAll


是否noitfyAll方法真的唤醒全部的Thread?
     是也不是。

全部等待中Thread都会被唤醒,但它们都还没要又一次取得对象的lock。所以这些Thread并非并行地运行:它们都必须等待对象lock被释放掉。

因此,一次仅仅有一个Thread可以运行,且仅仅有在调用notifyAll方法的这个Thread释放掉它的lock之后。


为什么要唤醒全部的Thread?
     1. 有多个Thread处于等待状态,无法指定哪一个收到通知
     2. 并不知道详细有多少个Thread处于等待,干脆同步通知。由等待中的Thread自己处理。

等待-通知机制与synchronized块
public class AnimatedCharacterDisplayCanvas extends CharacterDisplayCanvas implements CharacterListener, Runnable {

    private boolean done = true;
private int curX = 0;
private Thread timer = null;
private Object doneLock = new Object(); public AnimatedCharacterDisplayCanvas() {
} public AnimatedCharacterDisplayCanvas(CharacterSource cs) {
super(cs);
} public synchronized void newCharacter(CharacterEvent ce) {
curX = 0;
tmpChar[0] = (char) ce.character;
repaint();
} protected synchronized void paintComponent(Graphics gc) {
Dimension d = getSize();
gc.clearRect(0, 0, d.width, d.height);
if (tmpChar[0] == 0)
return;
int charWidth = fm.charWidth(tmpChar[0]);
gc.drawChars(tmpChar, 0, 1,
curX++, fontHeight);
} public void run() {
synchronized(doneLock) {
while (true) {
try {
if (done) {
doneLock.wait();
} else {
repaint();
doneLock.wait(100);
}
} catch (InterruptedException ie) {
return;
}
}
}
} public void setDone(boolean b) {
synchronized(doneLock) {
done = b; if (timer == null) {
timer = new Thread(this);
timer.start();
}
if (!done)
doneLock.notify();
}
}
}

二、条件变量

POSIX条件变量的四个基本函数:wait(), thimeed_wait(), signal, broadcast。直接相应Java提供的wait(), wait(long),notify(),notifyAll

     J2SE 5.0增加提供条件变量功能的类。

此类食欲Lock interface并用。由于这个新的interface是与调用以及lock对象分开的,它在用法上的灵活性就如筒其它Threading系统中的条件变量一样。

public class RandomCharacterGenerator extends Thread implements CharacterSource {
private static char[] chars;
private static String charArray = "abcdefghijklmnopqrstuvwxyz0123456789";
static {
chars = charArray.toCharArray();
} private Random random;
private CharacterEventHandler handler;
private boolean done = true;
private Lock lock = new ReentrantLock();
private Condition cv = lock.newCondition(); public RandomCharacterGenerator() {
random = new Random();
handler = new CharacterEventHandler();
} public int getPauseTime() {
return (int) (Math.max(1000, 5000 * random.nextDouble()));
} public void addCharacterListener(CharacterListener cl) {
handler.addCharacterListener(cl);
} public void removeCharacterListener(CharacterListener cl) {
handler.removeCharacterListener(cl);
} public void nextCharacter() {
handler.fireNewCharacter(this,
(int) chars[random.nextInt(chars.length)]);
} public void run() {
try {
lock.lock();
while (true) {
try {
if (done) {
cv.await();
} else {
nextCharacter();
cv.await(getPauseTime(), TimeUnit.MILLISECONDS);
}
} catch (InterruptedException ie) {
return;
}
}
} finally {
lock.unlock();
}
} public void setDone(boolean b) {
try {
lock.lock();
done = b; if (!done) cv.signal();
} finally {
lock.unlock();
}
}
}
     为什么使用Condition而不使用wait与notify?或者说是二者的差别?
     1. Condition与wait同样都是由于须要确保同步安全(即避免竞态条件)而必须使用锁机制保证。

     2. Lock对象不能与wait、notify方法搭配。由于这些方法已经在内部被用来实现Lock对象,持有lock对象并不表示持有了该对象的同步锁。
     3. Condition对象不像等待-通知机制,它是被创建不同的对象。

对每个Lock对象都能够创建一个以上的Condition对象。这表示我们能够针对个别的Thread或ThreadGroup进行独立的设定。



Condition方法:
void await()
     等待条件的发生。

void awaitUniterruptibly()
     等待条件的发生。

与await()不同,它的调用不可能被中断。

void signal()
     通知某个等待使用Condition对象的Thread此条件已经发生。
void signalAll()
     通知全部等待使用Condition对象的Thread此条件已经发生。






Java 线程第三版 第四章 Thread Notification 读书笔记的更多相关文章

  1. Java 线程第三版 第五章 极简同步技巧 读书笔记

    一.能避免同步吗? 取得锁会由于下面原因导致成本非常高:     取得由竞争的锁须要在虚拟机的层面上执行很多其它的程序代码.     要取得有竞争锁的线程总是必须等到锁被释放后. 1. 寄存器的效应 ...

  2. 《Java并发编程实战》第六章 任务运行 读书笔记

    一. 在线程中运行任务 无限制创建线程的不足 .线程生命周期的开销很高 .资源消耗 .稳定性 二.Executor框架 Executor基于生产者-消费者模式.提交任务的操作相当于生产者.运行任务的线 ...

  3. 《Java并发编程实战》第五章 同步容器类 读书笔记

    一.同步容器类 1. 同步容器类的问题 线程容器类都是线程安全的.可是当在其上进行符合操作则须要而外加锁保护其安全性. 常见符合操作包括: . 迭代 . 跳转(依据指定顺序找到当前元素的下一个元素) ...

  4. Java 线程第三版 第一章Thread导论、 第二章Thread的创建与管理读书笔记

    第一章 Thread导论 为何要用Thread ? 非堵塞I/O      I/O多路技术      轮询(polling)      信号 警告(Alarm)和定时器(Timer) 独立的任务(Ta ...

  5. Java 线程第三版 第九章 Thread调度 读书笔记

    一.Thread调度的概述 import java.util.*; import java.text.*; public class Task implements Runnable { long n ...

  6. Java 线程第三版 第八章 Thread与Collection Class 读书笔记

        JDK1.2引入最有争议性的改变是将集合类默觉得不是Thread安全性的. 一.Collection Class的概述 1. 具有Threadsafe 的Collection Class: j ...

  7. Java核心技术卷一基础知识-第7章-图形程序设计-读书笔记

    第7章 图形程序设计 本章内容: * Swing概述 * 创建框架 * 框架定位 * 在组件中显示信息 * 处理2D图形 * 使用颜色 * 文本使用特殊字体 * 显示图像 本章主要讲述如何编写定义屏幕 ...

  8. 《Java并发编程实战》第十三章 显示锁 读书笔记

    一.Lock与 ReentrantLock Lock 提供一种无条件的.可轮询的.定时的.可中断的锁获取操作,全部加锁和解锁的方法都是显式的. public interface Lock { void ...

  9. Javascript模式(第四章函数)------读书笔记

    一 背景 js函数的两个特点:1 函数是第一类对象(first-class object):2 函数可以提供作用域 1 函数是对象: 1 函数可以在运行时动态创建,还可以在程序执行过程中创建 2 可以 ...

随机推荐

  1. 五个案例让你明白GCD死锁(转)

    转自:http://ios.jobbole.com/82622/ 死锁一直都是在使用多线程时,需要注意的一个问题.以前对同步.异步,串行.并行只有一个模糊的概念,想想也是时候整理一下了.再看看之前的博 ...

  2. HttpClient与HttpUrlConnection下载速度比较

    Android有两套http的API,刚开始使用网络编程时多少有些迷惑到底用哪个好呢?其实孰优孰劣无需再争论,google已经指出HttpUrlConnection是Android更优的选择,并在SD ...

  3. 通俗易懂之Tensorflow summary类 & 初识tensorboard

    前面学习的cifar10项目虽小,但却五脏俱全.全面理解该项目非常有利于进一步的学习和提高,也是走向更大型项目的必由之路.因此,summary依然要从cifar10项目说起,通俗易懂的理解并运用sum ...

  4. 第12月第1天 MASConstraintMaker crash

    1. crash [valueLabel mas_makeConstraints:^(PAKitMASConstraintMaker *make) { make.left.equalTo(finish ...

  5. 第7月第11天 AVAsset

    1. An AVAsset defines the collective properties of the tracks that comprise the asset. (You can acce ...

  6. jquery的clone方法bug的修复select,textarea的值丢失

    项目中多次使用了iframe,但是操作起来是比较麻烦,项目中的现实情况是最外面是一个form,里面嵌套一个iframe,下面是一个其他的数据,在form提交的时候将iframe的数据和其他的数据一块提 ...

  7. H - Tickets dp

    题目链接: https://cn.vjudge.net/contest/68966#problem/H AC代码; #include<iostream> #include<strin ...

  8. USB-HID鼠标、键盘通讯格式【转】

    转自:https://blog.csdn.net/techhome803/article/details/9928873 转自:http://www.amobbs.com/forum.php?mod= ...

  9. C# 特性(Attribute)详细介绍

    1.什么是Atrribute 首先,我们肯定Attribute是一个类,下面是msdn文档对它的描述:公共语言运行时允许你添加类似关键字的描述声明,叫做attributes, 它对程序中的元素进行标注 ...

  10. Laravel中服务提供者和门面模式

    在laravel中,我们可能需要用到自己添加的类时,可以建立一个文件夹专门存放类文件,也可以使用laravel的服务提供者的方式来使用. 这两者其实区别不大,主要是前者使用的话,会跟业务代码产生依赖, ...