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

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

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

实战一下:

package duoxiancheng;

//测试lock锁
public class TestLock {
    public static void main(String[] args) {
        TestLock2 testLock2 = new TestLock2();
        new Thread(testLock2).start();
        new Thread(testLock2).start();
        new Thread(testLock2).start();
    }
}

class TestLock2 implements Runnable {

    int ticketNum = 10;
    @Override
    public void run() {
      while(true) {
          if(ticketNum > 0) {
              try {
                  Thread.sleep(1000);
              } catch (InterruptedException e) {
                  e.printStackTrace();
              }
              System.out.println(ticketNum--);
          } else {
              break;
          }
      }
    }
}

不加锁,是不安全的:
在这里插入图片描述
使用锁之后:

package duoxiancheng;

import java.util.concurrent.locks.ReentrantLock;

//测试lock锁
public class TestLock {
    public static void main(String[] args) {
        TestLock2 testLock2 = new TestLock2();
        new Thread(testLock2).start();
        new Thread(testLock2).start();
        new Thread(testLock2).start();
    }
}

class TestLock2 implements Runnable {

    int ticketNum = 10;

    //定义lock 锁
    private final ReentrantLock lock = new ReentrantLock();

    @Override
    public void run() {
      while(true) {
          try {
              //加锁
              lock.lock();
              if(ticketNum > 0) {
                  try {
                      Thread.sleep(1000);
                  } catch (InterruptedException e) {
                      e.printStackTrace();
                  }
                  System.out.println(ticketNum--);
              } else {
                  break;
              }
          } finally {
              //解锁
              lock.unlock();
          }

      }
    }
}

在这里插入图片描述
这样就能保证是线程安全的

synchronized与lock对比:

lock是显式锁,需要手动开启或者关闭锁,synchronized是隐式锁,出了作用域自动释放

lock只有代码块锁,synchronized有代码块锁和方法锁

使用lock锁,jvm花费较少的时间来调度线程,性能更好,并且具有更好的扩展性,提供更多的子类

优先使用顺序,lock -》 同步代码块(已经进入了方法体,分配了相应的资源)-》同步方法(在方法体之外)

好了,今天先到这里

Logo

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。

更多推荐