• java中的锁


    1.自旋锁是采用让当前线程不停地的在循环体内执行实现的,当循环的条件被其他线程改变时 才能进入临界区

    public class SpinLock {
    private AtomicReference<Thread> owner =new AtomicReference<>();
    public void lock(){
    Thread current = Thread.currentThread();
    while(!owner.compareAndSet(null, current)){
    }
    }
    public void unlock (){
    Thread current = Thread.currentThread();
    owner.compareAndSet(current, null);
    }
    }

    使用了CAS原子操作,lock函数将owner设置为当前线程,并且预测原来的值为空。unlock函数将owner设置为null,并且预测值为当前线程。

    当有第二个线程调用lock操作时由于owner值不为空,导致循环一直被执行,直至第一个线程调用unlock函数将owner设置为null,第二个线程才能进入临界区。

    由于自旋锁只是将当前线程不停地执行循环体,不进行线程状态的改变,所以响应速度更快。但当线程数不停增加时,性能下降明显,因为每个线程都需要执行,占用CPU时间。如果线程竞争不激烈,并且保持锁的时间段。适合使用自旋锁。

    2.可重入锁,也叫做递归锁,指的是同一线程 外层函数获得锁之后 ,内层递归函数仍然有获取该锁的代码,但不受影响。
    在JAVA环境下 ReentrantLock 和synchronized 都是 可重入锁。

    public class Test implements Runnable{

     public synchronized void get(){
      System.out.println(Thread.currentThread().getId());
      set();
     }

     public synchronized void set(){
      System.out.println(Thread.currentThread().getId());
     }

     @Override
     public void run() {
      get();
     }
     public static void main(String[] args) {
      Test ss=new Test();
      new Thread(ss).start();
      new Thread(ss).start();
      new Thread(ss).start();
     }
    }

    ReentrantLock与synchronized的区别

    1.ReentrantLock使用起来比较灵活,但是必须有释放锁的动作;

    2.ReentrantLock必须手动释放和开启锁,synchronized 不需要;

    3.ReentrantLock只适用与代码块锁,而synchronized 对象之间的互斥关系;

       
  • 相关阅读:
    ISP基础(01):ISP模块列表
    Linux 开发(02):打印特殊含义转义符
    note template
    apply、call、bind的区别
    Fiddle 抓包工具
    post和get的使用场景和区别
    闭包
    原型链
    node.js
    CSS垂直居中
  • 原文地址:https://www.cnblogs.com/dfyz/p/5738455.html
Copyright © 2020-2023  润新知