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. Linux安装Oracle调整tmpfs以突破1.7G的限制

    调整/dev/shm的大小 ---------------------------------------------------------1.查看大小 df -h /dev/shm [@more@ ...

  2. time,datetime,calendar模块

    Python中,与时间有关的模块有time,datetime和calendar. 1.时钟时间:time 在Python中,用三种方式来表示时间:时间戳,格式化时间字符串和结构化时间. 1)时间戳,就 ...

  3. 【转】检索 COM 类工厂中 CLSID 为 {00024500-0000-0000-C000-000000000046} 的组件失败,原因是出现以下错误: 80070005 拒绝访问

    源地址:https://www.cnblogs.com/love522/p/4462253.html 最近在做一个网站时,有一个下载word文档功能,在本地直接调试是可以下载的,但部署到IIS上就出现 ...

  4. HDU6342-2018ACM暑假多校联合训练4-1011-Problem K. Expression in Memories

    Problem K. Expression in Memories Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 262144/262 ...

  5. MySQL事务及事务隔离级别 锁机制

    什么是事务? 当多个用户访问同一份数据时,一个用户在更改数据的过程中可能有其他用户同时发起更改请求,为保证数据库记录的更新从一个一致性状态更改为另一个一致性状态,这样的操作过程就是事务.事务具有的AC ...

  6. Sql server 千万级大数据SQL查询优化的几点建议

    1.对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引. 2.应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索 ...

  7. js 简单数据类型和复杂数据类型的区别

    原始数据类型: number,string,boolean,undefined, null,object 基本类型(简单类型),值类型: number,string,boolean 复杂类型(引用类型 ...

  8. Spring学习笔记(五)—— Spring整合JDBC

    一.Spring对JDBC的支持 Spring提供了很多模板整合Dao技术 与JDBC的整合中,Spring中提供了一个可以操作数据库的对象——JdbcTemplate,该对象封装了JDBC技术,与D ...

  9. js、php 判断用户终端 、浏览器类型

    js 判断 用户使用终端 function isMobeil() { if ((navigator.userAgent.match(/(phone|pad|pod|iPhone|iPod|ios|iP ...

  10. Python常用的标准库以及第三方库有哪些?

    20个必不可少的Python库也是基本的第三方库 读者您好.今天我将介绍20个属于我常用工具的Python库,我相信你看完之后也会觉得离不开它们.他们是: Requests.Kenneth Reitz ...