有了synchronized为什么还要Lock?

因为Lock和synchronized比较有如下优点

1、 尝试非阻塞地获取锁

2、 获取锁的过程可以被中断

3、 超时获取锁

Lock的标准用法

 package com.lgs;

 import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock; /**
* lgs
* 显示锁lock的标准写法
*/
public class LockTemplete { public static void main(String[] args) {
Lock lock = new ReentrantLock();
//获取锁
lock.lock();
try{
// do my work.....
}finally{
//释放锁
lock.unlock();
}
} }

Lock的常用方法

Lock() 获取锁

tryLock尝试非阻塞地获取锁

lockInterruptibly:获取锁的过程可以被中断

tryLock(long time, TimeUnit unit) 超时获取锁

unlock()释放锁

锁的可重入

一个线程获得了锁进入了同步代码块遇到了锁仍然可以进入同步代码块

递归的时候发生锁的重入,没有锁的可重入,就会死锁

公平和非公平锁

公平锁,先对锁发出获取请求的一定先被满足。公平锁的效率比非公平锁效率要低。

为什么非公平锁的性能要高:因为非公平锁是可以插队的,如线程C被唤醒变为可执行去获取锁的过程中,线程A插队进来直接获取锁执行自己的业务,线程A执行完以后,线程C刚好唤醒完直接就获取锁运行了,这样在线程C唤醒的过程中线程A就执行完了效率更高

读写锁ReentrantReadWriteLock

允许多个读线程同时进行,但是只允许一个写线程(不允许其他读线程防止脏读和写线程),支持读多写少场景,性能会有提升。

 package com.lgs;

 import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.concurrent.locks.ReentrantReadWriteLock; /**
* lgs
* 读写锁的使用
*/
public class RwLockTemplete { static final Map<String,String> map = new HashMap<>();
static ReentrantReadWriteLock reentrantReadWriteLock = new ReentrantReadWriteLock();
static Lock r = reentrantReadWriteLock.readLock();
static Lock w = reentrantReadWriteLock.writeLock(); public void put(){
w.lock();
try{
// do my work.....
}finally{
w.unlock();
}
} public void get(){
r.lock();
try{
// do my work.....
}finally{
r.unlock();
}
} }

Condition接口有何用处?

Object的 wait,notify/notifyAll 实现等待通知机制

Condition接口和Lock配合来实现等待通知机制

Condition常用方法和使用范式

 package com.lgs;

 import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock; /**
* lgs
* Condition的使用方式
*/
public class ConditionTemplete { Lock lock = new ReentrantLock();
Condition condition = lock.newCondition(); public void waitc() throws InterruptedException {
lock.lock();
try{
condition.await();
}finally{
lock.unlock();
}
} public void waitnotify() throws InterruptedException {
lock.lock();
try{
condition.signal();
//condition.signalAll();尽量少使用
}finally{
lock.unlock();
}
} }

结合ReentrantLock和Condition实现线程安全的有界队列

 package com.lgs.bq;

 import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock; /**
* lgs
* 结合ReentrantLock和Condition实现线程安全的有界队列
*/
public class BlockingQueueLC<T> {
private List queue = new LinkedList<>();
private final int limit;
Lock lock = new ReentrantLock();
private Condition needNotEmpty = lock.newCondition();
private Condition needNotFull = lock.newCondition(); public BlockingQueueLC(int limit) {
this.limit = limit;
} public void enqueue(T item) throws InterruptedException {
lock.lock();
try{
while(this.queue.size()==this.limit){
needNotFull.await();
}
this.queue.add(item);
//通知出队线程有数据可以取了
needNotEmpty.signal();
}finally{
lock.unlock();
}
} public T dequeue() throws InterruptedException {
lock.lock();
try{
while(this.queue.size()==0){
needNotEmpty.await();
}
//通知入队线程有位置可以入队了
needNotFull.signal();
return (T) this.queue.remove(0);
}finally{
lock.unlock();
}
}
}
package com.lgs.bq;

/**
*
*/
public class BqTest {
public static void main(String[] args) {
BlockingQueueLC<Integer> bq = new BlockingQueueLC(10);
Thread threadA = new ThreadPush(bq);
threadA.setName("Push");
Thread threadB = new ThreadPop(bq);
threadB.setName("Pop");
threadB.start();
threadA.start();
} private static class ThreadPush extends Thread{
BlockingQueueLC<Integer> bq; public ThreadPush(BlockingQueueLC<Integer> bq) {
this.bq = bq;
} @Override
public void run() {
String threadName = Thread.currentThread().getName();
int i = 5;
while(i>0){
try {
Thread.sleep(500);
System.out.println(" i="+i+" will push");
bq.enqueue(i--);
} catch (InterruptedException e) {
//e.printStackTrace();
} }
}
} private static class ThreadPop extends Thread{
BlockingQueueLC<Integer> bq; public ThreadPop(BlockingQueueLC<Integer> bq) {
this.bq = bq;
}
@Override
public void run() {
while(true){
try {
Thread.sleep(1000);
System.out.println(Thread.currentThread().getName()+" will pop.....");
Integer i = bq.dequeue();
System.out.println(" i="+i.intValue()+" alread pop");
} catch (InterruptedException e) {
//e.printStackTrace();
}
} }
}
}

多线程系列三:Lock和Condition的更多相关文章

  1. java多线程系列(四)---Lock的使用

    Lock的使用 前言:本系列将从零开始讲解java多线程相关的技术,内容参考于<java多线程核心技术>与<java并发编程实战>等相关资料,希望站在巨人的肩膀上,再通过我的理 ...

  2. java多线程系列(三)---等待通知机制

    等待通知机制 前言:本系列将从零开始讲解java多线程相关的技术,内容参考于<java多线程核心技术>与<java并发编程实战>等相关资料,希望站在巨人的肩膀上,再通过我的理解 ...

  3. (Java多线程系列三)线程间通讯

    Java多线程间通讯 多线程之间通讯,其实就是多个线程在操作同一个资源,但是操作的动作不同. 1.使用wait()和notify()方法在线程中通讯 需求:第一个线程写入(input)用户,另一个线程 ...

  4. Java多线程系列三——实现线程同步的方法

    两种实现线程同步的方法 方法 特性 synchronized 不需要显式地加解锁,易实现 ReentrantLock 需要显式地加解锁,灵活性更好,性能更优秀,结合Condition可实现多种条件锁 ...

  5. 【Java多线程系列三】实现线程同步的方法

    两种实现线程同步的方法 方法 特性 synchronized  不需要显式的加锁,易实现 ReentrantLock 需要显式地加解锁,灵活性更好,性能更优秀,结合Condition可实现多种条件锁  ...

  6. Java多线程系列 JUC锁06 Condition条件

    Condition介绍 Condition中提供了一组类似于Object中的监视器方法.与Lock配合可以完成等待通知模式. Lock lock = new ReentrantLock(); Cond ...

  7. Java多线程系列十——BlockingQueue

    参考资料:http://ifeve.com/java-synchronousqueue/http://www.cnblogs.com/jackyuj/archive/2010/11/24/188655 ...

  8. java并发编程系列三、Lock和Condition

    有了synchronized为什么还要Lock? 因为Lock和synchronized比较有如下优点 1. 尝试非阻塞地获取锁 2. 获取锁的过程可以被中断 3. 超时获取锁 Lock的标准用法 p ...

  9. Java多线程系列--“JUC锁”06之 Condition条件

    概要 前面对JUC包中的锁的原理进行了介绍,本章会JUC中对与锁经常配合使用的Condition进行介绍,内容包括:Condition介绍Condition函数列表Condition示例转载请注明出处 ...

随机推荐

  1. python(43):collections模块

    Python作为一个“内置电池”的编程语言,标准库里面拥有非常多好用的模块.比如今天想给大家 介绍的 collections 就是一个非常好的例子. 基本介绍: 我们都知道,python拥有一些内阻的 ...

  2. Asp.Net解析json字符串

    方法一: using LitJson; string json= "{...........}"; JsonData jdData = JsonMapper.ToObject(js ...

  3. 转css中文英文换行、禁止换行、显示省略号

    css中文英文换行.禁止换行.显示省略号 原创 2016年08月09日 14:20:01   word-break:break-all;只对英文起作用,以字母作为换行依据 word-wrap:brea ...

  4. Hive中小表与大表关联(join)的性能分析【转】

    Hive中小表与大表关联(join)的性能分析 [转自:http://blog.sina.com.cn/s/blog_6ff05a2c01016j7n.html] 经常看到一些Hive优化的建议中说当 ...

  5. Excel2013 破解(编辑工作表受保护)密码

    在日常工作中,大家有时会遇到过这样的情况:使用Excel编制的报表.表格.程序等,在单元格中设置了公式.函数等,为了防止其他人修改您的设置或者防止您自己无意中修改,您可能会使用Excel的工作表保护功 ...

  6. JS 实现日期信息增加年数,月数,天数

    function DateAdd(interval, number, date) { /* * 功能:实现JSScript的DateAdd功能. * 参数:interval,字符串表达式,表示要添加的 ...

  7. LeetCode:Sqrt(x) 解题报告

    Sqrt(x) Implement int sqrt(int x). Compute and return the square root of x. SOLUTION 1: 参见:二分法总结,以及模 ...

  8. Java SWT编程基础

    SWT常用组件列表及使用 https://blog.csdn.net/u013310025/article/details/52939452 SWT编程基础-控件和图形资源 https://blog. ...

  9. Flask简介,安装,demo,快速入门

    1.Flask简介 Flask是一个相对于Django而言轻量级的Web框架. 和Django大包大揽不同,Flask建立于一系列的开源软件包之上,这其中 最主要的是WSGI应用开发库Werkzeug ...

  10. java框架篇---Struts入门

    首先理解Struts与MVC的关系 在传统的MVC模式中所有的请求都要先交给Servlet处理,之后由Servlet调用JavaBean,并将结果交给JSP中进行显示.结构图如下 Struts是Apa ...