Synchronized
- 概念:
重量级锁、重入锁、jvm 级别锁
使用:方法:ACC_SYNCHRONIZED、代码块 monitorenter\monitorexit
jvm 监视器 - 范围:方法和代码块(对象锁和类锁):
- 对于普通同步方法,锁是当前实例对象。 对于静态同步方法,锁是当前类的 Class 对象。 对于同步方法块,锁是 Synchonized
括号里配置的对象。
- 场景:
资源竞争
- Lock&ReentrantLock 写法:
try { lock.lock();} finally { lock.unlock();}
- void lock() 获取锁,调用该方法当前线程将会获取锁,当锁获取后,该方法将返回。
- void lockInterruptibly() throws InterruptedException 可中断获取锁,与 lock()方法不同之处在于该方
- 法会响应中断,即在锁的获取过程中可以中断当前线程
- boolean tryLock() 尝试非阻塞的获取锁,调用该方法立即返回,true 表示获取到锁
- boolean tryLock(long time,TimeUnit unit) throws InterruptedException 超时获取锁,以下情况会返回:
- 时间内获取到了锁,时间内被中断,时间到了没有获取到锁。
- void unlock() 释放锁
统计:
java.util.concurrent.locks.ReentrantLock#getHoldCount
java.util.concurrent.locks.ReentrantLock#getQueuedThreadsSynchronized 和 ReentrantLock 对比:
- Synchronized:jvm 层级的锁 自动加锁自动释放锁
- Lock:依赖特殊的 cpu 指令,代码实现、手动加锁和释放锁、Condition(生产消费模式)
- ReentrantReadWriteLock 读写锁
- 细粒度问题 ,读是共享的、写是独占的
- java8 增加了对读写锁的优化:StampedLock
- 实例代码
- static Lock可以锁注当前类 非静态的只能锁住当前类的实例对象
package com.itcode.锁;import java.util.concurrent.locks.Lock;import java.util.concurrent.locks.ReentrantLock;/** * @author 夏天 * @date 2020年10月29日 22:32 */public class ReentrantLock01 implements Runnable { private static int i = 0; static Lock lock = new ReentrantLock(); private void add() { lock.lock(); try { for (int i1 = 0; i1 < 5000; i1++) { i++; } } finally { lock.unlock(); } } @Override public void run() { add(); } public static void main(String[] args) throws InterruptedException { for (int j = 0; j < 20; j++) { i = 0; ReentrantLock01 sync01 = new ReentrantLock01(); ReentrantLock01 sync02 = new ReentrantLock01(); Thread t1 = new Thread(sync01); Thread t2 = new Thread(sync02); t1.start(); t2.start(); t1.join(); t2.join(); System.out.println(i); } }}
Lock之tryLock
使用方法:
try { if(lock.tryLock());} finally { //获取到锁在释放 如果不加条件判断 获取不到锁也会进行释放 会抛出异常IllegalMonitorStateException if (lock.isHeldByCurrentThread()) { lock.unlock(); }}
- tryLock()方法是有返回值的,它表示用来尝试获取锁,如果获取成功,则返回true,如果获取失败(即锁已被其他线程获取),则返回false,这个方法无论如何都会立即返回。在拿不到锁时不会一直在那等待。
- boolean tryLock(long timeout, TimeUnit unit) :
参数1 等待时间,参数2 时间单位
等待指定时间如果还获取不到锁返回false
实例代码:
package com.itcode.锁;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;import java.util.concurrent.TimeUnit;import java.util.concurrent.locks.Lock;import java.util.concurrent.locks.ReentrantLock;/** * @author 夏天 * @date 2020年10月29日 22:32 */public class ReentrantLock02 implements Runnable { private static int i = 0; ReentrantLock lock = new ReentrantLock(); @Override public void run() { try { if (lock.tryLock(4, TimeUnit.SECONDS)) { System.out.println(Thread.currentThread().getName() + "获取"); Thread.sleep(6000); } else { System.out.println(Thread.currentThread().getName() + "获取锁失败"); } } catch (InterruptedException e) { e.printStackTrace(); } finally { //注意 不加这个会报错 IllegalMonitorStateException 没有锁无法解锁 if (lock.isHeldByCurrentThread()) { lock.unlock(); } } } public static void main(String[] args) throws InterruptedException { ReentrantLock02 reentrantLock02 = new ReentrantLock02(); Thread t1 = new Thread(reentrantLock02); Thread t2 = new Thread(reentrantLock02); t1.start(); t2.start(); t1.join(); t2.join(); }}
ReentrantReadWriteLock 读写锁
细粒度问题 ,读是共享的、写是独占的
package com.itcode.锁;import java.util.concurrent.*;import java.util.concurrent.locks.ReentrantReadWriteLock;/** * @author 夏天 * @date 2020年10月29日 22:42 * 可以同时读 上了写锁后就不可以读了 */public class ReadWriterLockTest { ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); ReentrantReadWriteLock.WriteLock writeLock = lock.writeLock(); ReentrantReadWriteLock.ReadLock readLock = lock.readLock(); public String query() { readLock.lock(); try { Thread.sleep(50); System.out.println("读数据"); return "成功"; } catch (InterruptedException e) { e.printStackTrace(); return "成功"; } finally { readLock.unlock(); } } public void save() { writeLock.lock(); try { System.out.println("保存数据"); Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } finally { writeLock.unlock(); } } /** * 读50次 */ int readCount = 50; /** * 写5次 */ int writeCount = 5; public static void main(String[] args) throws InterruptedException, ExecutionException { ReadWriterLockTest readWriterLockTest = new ReadWriterLockTest(); //new Thread(() -> { // while (true) { // readWriterLockTest.query(); // } //}).start(); //new Thread(() -> { // while (true) { // try { // readWriterLockTest.save(); // } catch (InterruptedException e) { // e.printStackTrace(); // } // } //}).start(); CompletableFuture<String> queryFuture = CompletableFuture.supplyAsync(() -> { while (readWriterLockTest.readCount-- > 0) { readWriterLockTest.query(); } return "查询完成"; }); CompletableFuture<String> saveFuture = CompletableFuture.supplyAsync(() -> { while (readWriterLockTest.writeCount-- > 0) { readWriterLockTest.save(); } return "保存完成"; }); //等待所有线程结束 无法接受返回值 ,接收返回值使用anyOf CompletableFuture.allOf(queryFuture, saveFuture).get(); }}
原文转载:http://www.shaoqun.com/a/484780.html
eori:https://www.ikjzd.com/w/499
灰色清关:https://www.ikjzd.com/w/1409
bsci:https://www.ikjzd.com/w/2339
Synchronized概念:重量级锁、重入锁、jvm级别锁使用:方法:ACC_SYNCHRONIZED、代码块monitorenter\monitorexitjvm监视器范围:方法和代码块(对象锁和类锁):对于普通同步方法,锁是当前实例对象。对于静态同步方法,锁是当前类的Class对象。对于同步方法块,锁是Synchonized括号里配置的对象。场景:资源竞争Lock&Reentrant
腾邦:https://www.ikjzd.com/w/1382
美菜网:https://www.ikjzd.com/w/1874
2020广州万圣节晚上什么地方最刺激?万圣节广州夜场好玩活:http://tour.shaoqun.com/a/69544.html
亚马逊 Q&A 这么刷:https://www.ikjzd.com/home/5306
9月贸易新规来了!你一定不知道的一些重点!:https://www.ikjzd.com/home/128989
没有评论:
发表评论