sychronized、wait、notify、notifyAll、sleep

在多线程环境下,为了防止多个线程同时调用同一个方法、修改同一份变量,造成数据读取结果混乱,可以使用synchronized关键字,对一个方法或者代码块实现同步调用,即只能一个线程调用完此方法后,下一个线程才能调用此方法。

当synchronized修饰的是一个类方法时,使用的是此类的Monitor实现同步(锁)。

当synchronized修饰的是一个实例方法时,使用的是此实例的Monitor实现同步(锁)。

当synchronized修饰的是一个代码块时,使用的是括号中变量的Monitor实现同步(锁)。

在StringBuffer、Hashtable、Vector等类中,为了实现方法同步,大量使用了sychronized关键字修饰方法。

当sychronized修饰的方法或者代码块,执行sleep时,进入time_waiting阶段,并会继续持有锁,直到sleep结束,或者被interrupted,继续执行,直到释放锁。

当sychronized修饰的方法或者代码块,执行wait时,进入waiting阶段,并释放持有的锁,当收到notify通知,或者被interrupted后,会重新竞争获取到锁,才会继续运行。注意,此时虽然处于同步方法中,但其在wait时锁被释放了,只有重新竞争获得锁,才能继续运行。

在sychronized修饰的方法或者代码块中,如果执行notify,会唤醒一个waiting(同一个对象锁)中的线程进入runnable阶段,等到退出sychronized区域,waiting的线程获得锁继续执行进入running阶段;如果执行notifyAll方法,会唤醒所有waiting(同一个对象锁)中的线程,等到当前线程退出sychronized区域,所有waiting的线程竞争锁,未竞争获得锁的线程再次进入waiting阶段,等待唤醒。

ReentrantLock、Condition

使用ReentrantLock类实例化一个lock实例,并可以通过lock实例新建一个Condition实例。

使用时,先用lock实例的lock方法,获得锁,在获得锁的期间可以使用此lock的Condition实例,进行await、signal、singalAll方法,发送信号,进行线程间通信。

举一个阻塞队列的例子:

通过lock对象,新建了两个Condition:notEmpty、notFull。

执行add操作时,会检查list的元素个数是否达到最大值,达到时,等待notFull信号。

执行take操作时,会检查list的元素个数是否为0,为0时,等待notEmpty信号。

add执行成功时,会发送notEmpty信号,通知执行take的线程,等到add操作的lock执行unlock后,去获取数据。

take执行成功时,会发送notFull信号,通知执行add的线程,等到take操作的lock执行unlock后,在去添加数据。

注意:在Conditon发送各种信号之前,创建他们的lock必须执行lock()操作,获取锁;在Conditon发送各种信号之后,创建他们的lock必须执行unlock()操作,释放锁。

class MyQueue {
private ReentrantLock lock = new ReentrantLock();
private Condition notEmpty = lock.newCondition();
private Condition notFull = lock.newCondition();
private AtomicInteger count = new AtomicInteger(0);
private List<String> list = new LinkedList<String>();
private final int MaxCount = 10; public void add(String str) {
lock.lock();
try {
while (count.get() > MaxCount) {
notFull.await();
}
list.add(str);
count.incrementAndGet();
notEmpty.signal();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
} public String take() {
String retStr = null;
lock.lock();
try {
while (count.get() == 0) {
notEmpty.await();
}
retStr = list.remove(0);
count.decrementAndGet();
notFull.signal();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
return retStr;
}
}

java ReentrantLock Condition的更多相关文章

  1. java并发编程——通过ReentrantLock,Condition实现银行存取款

         java.util.concurrent.locks包为锁和等待条件提供一个框架的接口和类,它不同于内置同步和监视器.该框架允许更灵活地使用锁和条件,但以更难用的语法为代价. Lock 接口 ...

  2. java 多线程 Thread 锁ReentrantLock;Condition等待与通知;公平锁

    1,介绍: import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock;   在JA ...

  3. java ReentrantLock结合条件队列 实现生产者-消费者模式 以及ReentratLock和Synchronized对比

    package reentrantlock; import java.util.ArrayList; public class ProviderAndConsumerTest { static Pro ...

  4. 在Java的Condition接口【唤醒全部线程】

    在Java的Condition接口中,存在的几个方法跟Synchronized中的wait(),waitall(),wait(time ^),这个几个方法一一对应起来,但是在Lock.newCondi ...

  5. java ReentrantLock可重入锁功能

    1.可重入锁是可以中断的,如果发生了死锁,可以中断程序 //如下程序出现死锁,不去kill jvm无法解决死锁 public class Uninterruptible { public static ...

  6. java多线程-Condition

    Condition 将 Object 监视器方法(wait.notify 和 notifyAll)分解成截然不同的对象,以便通过将这些对象与任意 Lock 实现组合使用,为每个对象提供多个等待 set ...

  7. Java并发控制:ReentrantLock Condition使用详解

    生产者-消费者(producer-consumer)问题,也称作有界缓冲区(bounded-buffer)问题,两个进程共享一个公共的固定大小的缓冲区.其中一个是生产者,用于将消息放入缓冲区:另外一个 ...

  8. java线程并发控制:ReentrantLock Condition使用详解

    本文摘自:http://outofmemory.cn/java/java.util.concurrent/lock-reentrantlock-condition java的java.util.con ...

  9. Java ReEntrantLock 之 Condition条件(Java代码实战-002)

    import java.util.LinkedList; import java.util.concurrent.locks.Condition; import java.util.concurren ...

随机推荐

  1. 【bzoj4007】[JLOI2015]战争调度 暴力+树形dp

    Description 脸哥最近来到了一个神奇的王国,王国里的公民每个公民有两个下属或者没有下属,这种 关系刚好组成一个 n 层的完全二叉树.公民 i 的下属是 2 * i 和 2 * i +1.最下 ...

  2. 洛谷P4501/loj#2529 [ZJOI2018]胖(ST表+二分)

    题面 传送门(loj) 传送门(洛谷) 题解 我们对于每一个与宫殿相连的点,分别计算它会作为多少个点的最短路的起点 若该点为\(u\),对于某个点\(p\)来说,如果\(d=|p-u|\),且在\([ ...

  3. 洛谷P4016 负载平衡问题(费用流)

    传送门 嗯……完全不会……不过题解似乎讲的挺清楚…… 考虑一下,每一个仓库最终肯定都是平均数,所以数量大于平均数的可以往外运,小于平均数的要从别的地方运进来 考虑建一个超级源$S$和超级汇$T$,并把 ...

  4. eclipse中查看java源码时,出现source not found问题

  5. python 第三次作业

    习题1: **1.初始化一个数据集,包括5-10位同学的成绩数据(数据类型不限),数据格式如下: **学号 姓名 Java C语言 Python 2017XXXX 小白 87 68 92 2017XX ...

  6. 20165224 陆艺杰 《Java程序设计》课程总结

    每周作业链接汇总 https://www.cnblogs.com/lyj-/p/8414278.html https://www.cnblogs.com/lyj-/p/8695018.html htt ...

  7. tomcat更改web文件路径

    由于代码太长,记不住!只能自己做个小笔记了!! <Context path="/" docBase="/opt/appl/merch.bak" debug ...

  8. MAC office2016 安装及激活(试了一下,靠谱, 非常感谢原作者)

    转载地址:https://blog.csdn.net/jxq0816/article/details/77248462 非常感谢原作者. 一.安装包下载地址 http://officecdn.micr ...

  9. Foremost恢复Linux中已删除的文件

    Foremost 我们只能在Linux中恢复已删除的文件,只要这些扇区在硬盘上没有被覆盖. 首先安装 要在CentOS上安装Foremost,我们将从官方网页下载并安装最前面的rpm.打开终端并执行以 ...

  10. C++_友元3-其他友元关系

    友元和类的关系还可以更复杂. 举个例子,假设出现了交互式遥控器,交互式遥控器能够让您回答电视节目中的问题,如果回答错误,电视将在控制器上产生嗡嗡声. 这个例子的问题,可以使用新的友元关系来解决.我把它 ...