java多线程:Lock(锁)

Lock(锁)

  • 从JDK5.0开始,Java提供了更强大的线程同步机制——通过显式定义同步锁对象来实现同步。同步锁使用Lock对象充当

  • java.util.concurrent.locks.Lock接口是控制多个线程对共享资源进行访问的工具。锁提供了对共享资源的独占访问,每次只能有一个线程对Lock对象加锁,线程开始访问共享资源之前应先获得Lock对象

  • ReentrantLock类实现了Lock(一个可重入的互斥锁),它拥有与synchronized相同的并发性和内存语义,在实现线程安全的控制中,比较常用的是 ReentrantLock,可以显式加锁、释放锁

  • //使用 lock 块来调用 try,在之前/之后的构造中,最典型的代码如下: 
     class X {
       private final ReentrantLock lock = new ReentrantLock();
       // ...
    
       public void m() { 
         lock.lock();  
         try {
           // ... method body  保证线程安全的代码
         } finally {
           lock.unlock()
               //如果同步代码有异常,要将unlock()写入finally语句块
         }
       }
     }
    
    import java.util.concurrent.locks.ReentrantLock;
    //测试Lock锁
    public class TestLock {
        public static void main(String[] args) {
            TestLock2 testLock2 = new TestLock2();
            new Thread(testLock2,"aa").start();
            new Thread(testLock2,"bb").start();
            new Thread(testLock2,"cc").start();
        }
    }
    class TestLock2 implements Runnable{
        int ticketNums = 1000;
        //定义lock锁
        private final ReentrantLock lock = new ReentrantLock();
        @Override
        public void run() {
            while (true) {
    
                try {
                    lock.lock();//加锁
                    if (ticketNums > 0) {
                        try {
                            Thread.sleep(100);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        System.out.println(Thread.currentThread().getName()+ticketNums--);
                    } else {
                        break;
                    }
                }finally {
                    //解锁
                    lock.unlock();
                }
    
            }
        }
    }
    

synchronized 与 Lock 的对比

  • Lock是显式锁(手动开启和关闭锁,别忘记关闭锁)

    synchronized是隐式锁,出了作用域自动释放

  • Lock只有代码块锁, synchronized有代码块锁和方法锁

  • 使用Lock锁,JVM将花费较少的时间来调度线程,性能更好。并且具有更好的扩展 性(提供更多的子类)

  • 优先使用顺序:

    • Lock > 同步代码块(已经进入了方法体,分配了相应资源) > 同步方法(在方法体之外)
posted @ 2021-01-24 17:27  迪迦是真的  阅读(374)  评论(0)    收藏  举报
//复制代码按钮 //代码行号 //评论