Java多线程-Lock(锁)

128 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第32天,点击查看活动详情

加锁:lock(),解锁:unLock(),一般放在try catch finally中使用

lock是JUC(并发)下的一个接口,一般用它的实现类ReentrantLock(可重入锁)比较多

  1. 从JDK5.0开始,Java提供了更加强大的线程同步机制,Lock是显示锁(手动开启和关闭锁,别忘了关闭锁),同步锁对象来实现同步,同步锁使用Lock对象充当,
  2. java.util.concurrent(并发).locks.Lock接口是控制多个线程对共享资源进行访问的工具,锁提供了对共享资源的独占访问,每次只能有一个线程对Lock对象加锁,线程开启访问共享资源之前应先获得Lock对象
  3. ReentrantLock类实现了Lock,它拥有synchronized相同的并发性和内存语义,在现实线程安全的控制中,比较常用的是ReentrantLock,可以显示加锁,释放锁

lock一般代码结构

lock加锁线程安全案例



package com.wyh.thread;



import java.util.concurrent.locks.ReentrantLock;



 /**

 *  @program:  Thread

 *  @description:  测试lock锁

 *  @author:  魏一鹤

 *  @createDate:  2022-01-16 20:48

 **/



public class TestLock {

     public static void main(String[] args){

         Lock lock = new Lock();

         new Thread(lock, "张三" ).start();

         new Thread(lock, "李四" ).start();

         new Thread(lock, "王五" ).start();

     }

}



class Lock implements Runnable{

    //票数

  int nums=10;

    //定义lock锁

  private  final ReentrantLock reentrantLock=new ReentrantLock();

    @Override

    public void run() {

        while (true) {

            try {

                reentrantLock.lock(); //加锁

  if (nums > 0) {

                    Thread.sleep(1000);

                    System.out.println(Thread.currentThread().getName() + "买到了" + nums-- + "张票" );

                } else {

                    break;

                }

            } catch (Exception e) {

                e.printStackTrace();

            } finally {

                //解锁

  reentrantLock.unlock();

            }

        }

    }

}

synchronzied和lock的区别

  1. synchronized是java内置关键字,lock是JUC下的接口
  2. synchronized是隐示锁,出了作用域自动释放(同步方法或者同步代码块),,lock是显示锁(手动开启和关闭锁,别忘了关闭锁)
  3. synchronized会自动释放锁,Lock需在finally中手工释放锁(unlock()方法释放锁),否则容易造成线程死锁
  4. Lock锁适合大量同步的代码的同步问题,synchronized锁适合代码少量的同步问题,使用lock锁,JVM将花费较少的时候来调度线程,性能更好,并且具有更好的扩展性(提供更多子类)
  5. Lock锁只有代码块锁,synchronized有代码块锁和方法锁

优先使用顺序

Lock锁>同步代码块(已经进入了方法体,分配了相应资源)>同步方法(在方法体外)