Java多线程知识点整理(Lock锁)
2019独角兽企业重金招聘Python工程师标准>>>
1.Lock的使用
private Lock lock = new ReentrantLock();public void test(){lock.lock();System.out.println("#######");lock.unlock();}
注意:try-catch-finally结合使用,unlock()在finally里面。
2.使用condition实现等待/通知
关键字synchronized与wait()和notify()/notifyAll()方法相结合可以实现等待/通知模式,类ReentrantLock也可以实现同样的功能,但需要借助Condition对象。可以实现多路通知功能,也就是在一个Lock对象里面可以创建多个Condition实例,线程对象可以注册在指定Condition中,从而可以有选择性进行线程通知,在调度线程上更加灵活。
synchronized的wait()和notify(),而Condition对象,却可以选择性通知。
2.1 使用condition API
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;public class test5 {private Lock lock = new ReentrantLock();public Condition condition1 = lock.newCondition();public Condition condition2 = lock.newCondition();public void awaitA(){try {lock.lock();System.out.println("A等待");condition1.await();} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}finally{lock.unlock();}}public void awaitB(){try {lock.lock();System.out.println("B等待");condition2.await();} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}finally{lock.unlock();}}public void signalA(){try {lock.lock();System.out.println("通知a");condition1.signalAll();} finally {lock.unlock();}// TODO: handle finally clause}public void signalB(){try {lock.lock();System.out.println("通知B");condition2.signalAll();} finally {lock.unlock();}// TODO: handle finally clause}public static void main(String[] args) {test5 t5 = new test5();//创建两个线程// Thread thread1= new Thread(t5);//Thread thread2= new Thread(t5);//只通知线程1//t5.signalA();}
}
2.2、生产者与消费模式:交替打印
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;public class test6 {private Lock lock =new ReentrantLock();private Condition condition= lock.newCondition();private boolean hasValue= false;public void set(){try {lock.lock();while(hasValue == true){condition.await();}System.out.println("@@@");hasValue= true;condition.signal();} catch (Exception e) {// TODO: handle exception}finally {lock.unlock();}}public void get(){try {lock.lock();while(hasValue == false){condition.await();}System.out.println("###");hasValue= false;condition.signal();} catch (Exception e) {// TODO: handle exception}finally {lock.unlock();}}public static void main(String[] args) {test6 test6 = new test6();//创建两个线程//启动}
}
注意:多消费者和多生产者,使用condition.signalAll();
3.公平锁与非公平锁
锁Lock分为“公平锁”和“非公平锁”,公平锁表示线程获取的顺序是按照线程加锁的顺序来分配的,即先来得的FIFO先进先出的顺序。而非公平锁就是一种获取抢占机制,是随机获得锁的,和公平锁不一样就是先来得不一定先得到锁,这个方式可能造成某些线程一直拿不到锁,结果也就是不公平的了。
import java.util.concurrent.locks.ReentrantLock;public class test7 {private ReentrantLock lock;public test7(boolean isFair){//传入true表示公平锁,反之为非公平锁super();lock = new ReentrantLock();}public void add(){try {lock.lock();} finally {lock.unlock();}}
}
4.API讲解
4.1、方法lockInterruptibly()
该方法的作用是:如果当前线程未被中断,则获取锁定,如果已经被中断则抛出异常。
4.2、tryLock()
改方法的作用是:仅在调用时锁定未被另一个线程保持的情况下,才获取该锁。
private Lock lock = new ReentrantLock();public void test(){if(lock.tryLock()){System.out.println("#######");}}
同时,tryLock(long timeout,TimeUnit unit)的作用是,如果锁定在给等待时间内没有被另一个线程保持,且当前线程未被中断,则获取该锁定。
4.3、使用Condition实现顺序执行
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;public class test8 {volatile private static int nextPrintWho =1;private static ReentrantLock lock = new ReentrantLock();final private static Condition conditionA = lock.newCondition();final private static Condition conditionB = lock.newCondition();final private static Condition conditionC = lock.newCondition();public static void main(String[] args) {Thread threadA = new Thread(){@Overridepublic void run() {try {lock.lock();while(nextPrintWho != 1){conditionA.await();}for(int i=1; i<4;i++){System.out.println("ThreadA"+i);}nextPrintWho = 2;conditionB.signalAll();} catch (Exception e) {// TODO: handle exception}finally {lock.unlock();}}};Thread threadB = new Thread(){@Overridepublic void run() {try {lock.lock();while(nextPrintWho != 2){conditionB.await();}for(int i=1; i<4;i++){System.out.println("ThreadB"+i);}nextPrintWho = 3;conditionC.signalAll();} catch (Exception e) {// TODO: handle exception}finally {lock.unlock();}}};Thread threadC = new Thread(){@Overridepublic void run() {try {lock.lock();while(nextPrintWho != 3){conditionC.await();}for(int i=1; i<4;i++){System.out.println("ThreadC"+i);}nextPrintWho = 1;conditionA.signalAll();} catch (Exception e) {// TODO: handle exception}finally {lock.unlock();}}};Thread[] aAray =new Thread[5];Thread[] bAray =new Thread[5];Thread[] cAray =new Thread[5];for(int i=0;i<5;i++){aAray[i] =new Thread(threadA);bAray[i] =new Thread(threadB);cAray[i] =new Thread(threadC);aAray[i].start();bAray[i].start();cAray[i].start();}}
}
总结:实现线程的顺序执行,可以使用:join方法,也可以使用Condition。
5.使用ReentrantReadWriteLock类
读写锁表示有两个锁,一个是读操作相关的锁,也称为共享锁;另一个是写操作相关的的锁,也叫排它锁。也就是多个读锁之间不互斥,读锁与写锁互斥,写锁与写锁互斥。在没有线程进行写入操作时,进行读取操作的多个线程都可以获取锁,而进行写入的操作的线程只有在获取写锁后才能进行操作。即多个线程可以同时进行读取操作,但是同一时刻只允许一个线程进行写入操作。
import java.util.concurrent.locks.ReentrantReadWriteLock;public class test9 {private ReentrantReadWriteLock lock = new ReentrantReadWriteLock();public void read(){try {lock.readLock();} catch (Exception e) {// TODO: handle exception}finally {lock.readLock().unlock();}}public void wirte(){try {lock.writeLock();} catch (Exception e) {// TODO: handle exception}finally {lock.writeLock().unlock();}}
}
转载于:https://my.oschina.net/u/2380961/blog/1595357
Java多线程知识点整理(Lock锁)相关推荐
- Java多线程知识点整理(线程池)
2019独角兽企业重金招聘Python工程师标准>>> 1.线程池的使用 线程池一般配合队列一起工作,是线程池限制并发处理任务的数量.然后设置队列的大小,当任务超过队列大小时,通过一 ...
- Java基础知识点整理(2022年最新版)
看了网上很多关于Java基础知识点整理的文章,但是感觉都不是很好,要么不全面,要么不准确,要么排版太乱了,所以今天整理了一份Java基础知识点整理(2022年最新版),希望对大家有帮助哈~ 由于本文篇 ...
- java基础知识点整理一
java基础知识点整理一 引言 '''突然发觉任何一门语言的基础知识部分,都比较杂一些.如果个人经过梳理之后,知识体系系统化,可以让基础更加牢靠一些.但是还是会有一些遗忘.所以,我想把一些比较重要但是 ...
- java 多线程 串行 加锁_java多线程 synchronized 与lock锁 实现线程安全
如果有多个线程在同时运行,而这些线程可能会同时运行这段代码.程序每次运行结果和单线程运行的结果是一样 的,而且其他的变量的值也和预期的是一样的,就是线程安全的. 通过卖火车票的例子 火车站要卖票,我们 ...
- 最全最新的的Java核心知识点整理!!! 【推荐】
前言: 想要文档版的小伙伴们可以私信我领取哦,更加清晰 一目了然 ~ Java核心知识点! 博客整理出来的稍微有点乱~ 目录 目录 -1 JVM - 19 2.1. 线程 - 20 2.2. JVM ...
- Java多线程4:synchronized锁机制
脏读 一个常见的概念.在多线程中,难免会出现在多个线程中对同一个对象的实例变量进行并发访问的情况,如果不做正确的同步处理,那么产生的后果就是"脏读",也就是取到的数据其实是被更改过 ...
- Java多线程 ——线程基础和锁锁锁
Java多线程(一) 一.线程的定义 二.Synchronize线程同步 三.偏向锁.自旋锁.重量级锁 四.volatile关键字 4.1.普通变量运算的物理意义 4.2.有无解决的方案 4.3.vo ...
- JAVA 多线程知识点
线程创建的方式 继承Thread类,重写run方法 实现Runnable接口 实现Callable接口 获取线程ID和线程名称 Thread子类中调用this.getId()或者this.getNam ...
- 多线程 流水线 java_Java Lock锁多线程中实现流水线任务
下面程序代码通过使用Lock锁执行简单的流水线任务: import java.util.concurrent.locks.Condition; import java.util.concurrent. ...
最新文章
- 自然语言处理中文本的token和tokenization
- 有互感的电感的串并联
- Day4-Springmvc表单数据
- lzw编码过程详解_编码拓展——封装、编码、码率
- 同时买票是怎么实现的_刷脸进站,语音买票!广州地铁这波操作666~
- Listener(监听器)
- hadoop安装以及Java API操作hdfs
- 《深入理解 Spring Cloud 与微服务构建》第十六章 Spring Boot Security 详解
- Entity Framework 学习中级篇1—EF支持复杂类型的实现
- 太强了,终于彻底搞懂 Nginx 的五大应用场景~
- Uber花了21亿元入驻上海自贸区 不叫优步叫雾博
- VID = 058F PID = 6387 可用的量产工具
- 我们,让9300万人办事少跑一趟
- 用Python实现视频字符化(蔡徐坤唱跳Rap视频)
- 拯救者win10重置系统出现“初始化出现错误,未进行任何更改”问题解决方法
- 索尼爱立信滑盖机java_可爱Walkman滑盖机 索尼爱立信W100i评测
- R语言通过WinBUGS对MGARCH和MSV模型进行贝叶斯估计和比较
- uniapp上传(拍照、本地),预览,删除图片
- docker redis
- 【安全开发】IOS安全编码规范