根据 jdk 对 Lock 接口的描述, Lock 实现提供比使用 synchronized 方法和语句可以获得的更广泛的锁定操作. 它们允许更灵活的结构化, 可能具有完全不同的属性, 并且可以支持多个相关联的对象 Condition .
synchronized 是 Java 的一个关键字, 而 Lock 是一个接口. Lock 锁是一种比 synchronized 关键字更加灵活的锁, 在线程通信中, synchronized 锁在线程通信中有 wait(阻塞线程, 释放锁) 和 notisfy(随机唤醒一个线程) 和 notisfyAll(唤醒所有线程) 三个方法. 在线程通信中不能指定唤醒某一个线程, 只能将所有线程都唤醒都进行判断, 再决定那个线程运行下去, 这样在很多情形下都会造成资源的浪费, 形成不必要的开销. 而 lock 锁提供的 API 可以单独指定某个线程唤醒, 这样在对线程的执行流程有规定的情形下, 比用 synchronized 关键字更加灵活和实用.
例如下列情形: 三个线程, 要求线程一打印 1-5 五个数, 之后线程 2 打印 1-10 十个数, 线程 3 打印 1-15 十五个数, 之后线程一打印 5 个数, 线程二打印 10 个数...... 循环 5 个循环.
应用 Lock 锁进行线程通信的方法:
- import java.util.concurrent.locks.Condition;
- import java.util.concurrent.locks.Lock;
- import java.util.concurrent.locks.ReentrantLock;
- public class Print_01 {
- public static void main(String[] args) {
- Print print = new Print();
- new Thread(()->{
- for (int i=0;i<5;i++) {
- print.print5();
- }
- },"A 线程").start();
- new Thread(()->{
- for (int i=0;i<5;i++) {
- print.print10();
- }
- },"B 线程").start();
- new Thread(()->{
- for (int i=0;i<5;i++) {
- print.print15();
- }
- },"C 线程").start();
- }
- }
- class Print{
- private int count=3;
- // 使用 lock 锁
- Lock lock=new ReentrantLock();
- Condition conditio1=lock.newCondition(); // 一把钥匙
- Condition conditio2=lock.newCondition(); // 一把钥匙
- Condition conditio3=lock.newCondition(); // 一把钥匙
- public void print5(){
- lock.lock();
- try {
- // 判断
- while(count!=1){
- conditio1.await();
- }
- // 干活
- for (int i = 1; i <=5; i++) {
- System.out.print(Thread.currentThread().getName()+i);
- System.out.println();
- }
- // 通知
- count=2;
- conditio2.signal();
- } catch (Exception e) {
- e.printStackTrace();
- } finally {
- lock.unlock();
- }
- }
- public void print10(){
- lock.lock();
- try {
- // 判断 多线程下的判断必须要用 while, 线程唤醒后要再次判断, 否则会造成虚假唤醒 (三个线程及以上就会出问题)
- while(count!=2){
- conditio2.await();
- }
- // 干活
- for (int i = 1; i <=10; i++) {
- System.out.print(Thread.currentThread().getName()+i);
- System.out.println();
- }
- // 通知
- count=3;
- conditio3.signal();
- } catch (Exception e) {
- e.printStackTrace();
- } finally {
- lock.unlock();
- }
- }
- public void print15(){
- lock.lock();
- try {
- while(count!=3){
- conditio3.await();
- }
- for (int i = 1; i <=15; i++) {
- System.out.print(Thread.currentThread().getName()+i);
- System.out.println();
- }
- count=1;
- conditio1.signal();
- } catch (Exception e) {
- e.printStackTrace();
- } finally {
- lock.unlock();
- }
- }
- }
来源: http://www.bubuko.com/infodetail-3323233.html