今天暂时把理论放这里,后续补充代码实践:
1 package com.cheng2839.test; 2 3 import java.util.concurrent.locks.Lock; 4 import java.util.concurrent.locks.ReadWriteLock; 5 import java.util.concurrent.locks.ReentrantLock; 6 import java.util.concurrent.locks.ReentrantReadWriteLock; 7 8 /** 9 * Lock学习 10 */ 11 public class MyTest011 { 12 13 public void packageClaList() { 14 //学习包 java.util.concurrent.locks. 下的类 15 16 /** 17 * 获取锁: 18 * lock() 无返回值 19 * tryLock() 有返回值 20 * tryLock(long time, TimeUnit unit) 在一定时间内获取锁 21 * lockInterruptibly() 未获取到锁,会响应中断(抛出异常) 22 * 23 * 释放锁: 24 * unLock() 25 */ 26 27 // ReentrantLock: 可重入锁 唯一实现Lock接口 28 Lock lock = new ReentrantLock(); 29 30 /** 31 * ReadWriteLock: 读写锁 接口 32 * 33 * ReentrantReadWriteLock: 实现类 34 * readLock():获取读锁 35 * writeLock():获取写锁 36 */ 37 ReadWriteLock rwLock = new ReentrantReadWriteLock(); 38 rwLock.readLock().lock(); 39 //如果有一个线程已经占用了读锁,则此时其他线程要申请读锁,也可以同时获取到读锁。 40 //如果有一个线程已经占用了读锁,则此时其他线程如果要申请写锁,则申请写锁的线程会一直等待释放读锁。 41 //如果有一个线程已经占用了写锁,则此时其他线程如果申请写锁或者读锁,则申请的线程会一直等待释放写锁。 42 43 44 /** 45 * Lock和synchronized有以下几点不同: 46 * 47 * 1)Lock是一个接口,而synchronized是Java中的关键字,synchronized是内置的语言实现; 48 * 2)synchronized在发生异常时,会自动释放线程占有的锁,因此不会导致死锁现象发生; 49 * 而Lock在发生异常时,如果没有主动通过unLock()去释放锁,则很可能造成死锁现象, 50 * 因此使用Lock时需要在finally块中释放锁; 51 * 3)Lock可以让等待锁的线程响应中断,而synchronized却不行,使用synchronized时, 52 * 等待的线程会一直等待下去,不能够响应中断; 53 * 4)通过Lock可以知道有没有成功获取锁,而synchronized却无法办到。 54 * 5)Lock可以提高多个线程进行读操作的效率。 55 * 56 * 在性能上来说,如果竞争资源不激烈,两者的性能是差不多的,而当竞争资源非常激烈时(即有大量线程同时竞争), 57 * 此时Lock的性能要远远优于synchronized。所以说,在具体使用时要根据适当情况选择。 58 */ 59 60 /** 61 * 1. 可重入锁 62 * 如果锁具备可重入性,则称作为可重入锁。像synchronized和ReentrantLock都是可重入锁, 63 * 可重入性实际上表明了锁的分配机制:基于线程的分配,而不是基于方法调用的分配。 64 * 举个简单的例子,当一个线程执行到某个synchronized方法时,比如说method1,而在method1中会调用另外一个synchronized方法method2,此时线程不必重新去申请锁,而是可以直接执行方法method2。 65 * 简单的理解:线程已经具备锁,不必再申请锁,可一直执行完毕。 66 * 67 * 2. 可中断锁 68 * 在Java中,synchronized就不是可中断锁,而Lock是可中断锁。 69 * 70 * 3. 公平锁 71 * 公平锁即尽量以请求锁的顺序来获取锁。 72 * synchronized就是非公平锁,它无法保证等待的线程获取锁的顺序。 73 * 而对于ReentrantLock和ReentrantReadWriteLock,它默认情况下是非公平锁,但是可以设置为公平锁。 74 * ReentrantLock中静态内部类:1)NotFairSync实现非公平锁;2)FairSync实现公平锁 75 * ReentrantLock lock = new ReentrantLock(true); 参数为true表示为公平锁,为fasle为非公平锁 76 * 77 * 4. 读写锁 78 * 正因为有了读写锁,才使得多个线程之间的读操作不会发生冲突。 79 * ReadWriteLock就是读写锁,它是一个接口,ReentrantReadWriteLock实现了这个接口。 80 * 可以通过readLock()获取读锁,通过writeLock()获取写锁。 81 */ 82 83 84 /** 85 * Object下的锁: 86 * wait():释放占有的对象锁 87 * notify(): 该方法会唤醒因为调用对象的wait()而等待的线程 88 * notifyAll()则是唤醒所有等待的线程 89 * 90 * 学习地址:https://www.cnblogs.com/fenjyang/p/11603229.html 91 */ 92 } 93 94 95 }
学习wait、notify和synchronized及Lock
原文:https://www.cnblogs.com/cheng2839/p/12721519.html