首页 > 其他 > 详细

常见的锁的概念

时间:2019-10-07 16:24:33      阅读:90      评论:0      收藏:0      [点我收藏+]

常见的锁的概念

  1. 可重入锁
  2. 公平锁/非公平锁
  3. 独享锁/共享锁
  4. 互斥锁/读写锁
  5. 乐观锁/悲观锁
  6. 分段锁
  7. 偏向锁/轻量级锁/重量级锁
  8. 自旋锁

修改 使用锁 或者同步机制
仅仅给变量添加volatile 是不行的 还会出现多卖少买状况
synchronized 简介 :非常经典的处理手段,具体使用有多种形式,它的核心思想就是修饰一个方法或者一段代码,这段代码不能同时两个以上的线程同时运行。
代码块 中的this 是调用该方法的对象 一般都是使用代码块
理解一下synchronized 直译过来 是同步的意思 但是我们京城称呼其为一种锁,为什么叫锁,原则上每个对象都可以持有一把锁,当某一个线程操作这个对象时, 这个线程就获得该对象的锁,在此期间其他线程就无法操作该对象了

Lock
简介:Lock是自JDK1.5 之后推出的一个接口,当热也是一系列子实现类,接口非常重要,定义了Java所认定的锁的概念,跟synchronized有显著区别,
synchronized是一个关键字,使用它可以实现类似锁的效果,但是严格的来说它并不是锁,Lock是一个接口,详细描述了锁的概念,其中重点包含若干方法,这些方法就是核心内容了。
方法:

lock():这个方法用来加锁,或者可以理解为获取对象的锁,如果获取成功,就执行下面的代码,若获取失败则一直等待,重复尝试获取

lockInterruptibly(); 也是尝试获取锁,但是对应带了Interrupter这个部分,所以对于获取锁的结果会进行进一步工作;

tryLock(); 尝试获取锁,返回值boolean类型,会返回获取锁的结果,跟lock()不一样,如果获取失败,返回false ,并且不会继续尝试获取;

unlock():解锁,运行之后即可释放锁,就能让其他线程获取了;

ReentrantLock:
是最常用的子实现类,加强对它的熟悉字面翻译它叫重入锁,确实它也是符合重入锁的要求,但是它仅仅可以表示重入锁。

可重入锁:
是一个概念,可重用锁在大部分时候并不直接表示RenntrantLock,可重用锁强调的是一种类型,这个类型关键特点是可重入,什么是可重入?
就是一个已经获得锁的线程还能继续调用加锁的代码。
这里我们强调可重入是一种典型的锁的类型,我们自己可以编码实现一些可重入锁,在实际项目中它的运用可以体现灵活性等等诸多优势点,就不一一展开。

ThreadDemo类

/**
 * @Author: Jiangjun
 * @Date: 2019/10/7 11:53
 * @Description: 描述购票的逻辑
 */
public class ThreadDemo implements Runnable{

    Lock lock = new ReentrantLock();

    volatile int num = 20;
    @Override
    public void run() {

        lock.lock();
        while (num>0){
            addlock();
            System.out.println(Thread.currentThread().getName() + "认为此时还有票可选");
            num = num - 1;
            System.out.println(Thread.currentThread().getName() + "买到了一张票,还剩" + num);
        }
        lock.unlock();

    }

    public  void addlock(){
        lock.lock();
    }

}

主函数:

public class TestMain {
    public static void main(String[] args) {

        ThreadDemo td = new ThreadDemo();

        Thread t1 = new Thread(td,"掌上编程");
        Thread t2 = new Thread(td,"公众号");
        t1.start();
        t2.start();

    }
}

公平锁:

公平=先来后到,先来的获取锁,就来的后获取锁。
同样公平锁也是一种概念,也是一种锁的类型,如果设计锁的机制符合公平要求,那么这个锁就是公平的锁。

若适用购票场景,如果强调先来后到,(从性能角度考虑)就必须采取特备的方案来实现这种先后顺序,这样必然会带来性能损失,所以公平锁的性能会劣于非公平锁。

如果我们使用非公平锁也会带带来一定风险,容易造成真实意义上的不公平,就有一些线程老早就在等待了,但是运气不好一直拿不到锁,这个可以成为锁饥饿现象。

因此我们强调根据情况来选择锁是否公平,一般如果要力避免掉锁饥饿现象,就要考虑使用公平锁,否则可以使用非公平锁。

Synchronized 只能是非公平锁
ReentrantLock 是后来加入的类,所以在设计上更加完善,可以直接通过构造函数来制定锁是否公平。
细节注意:

养成比较规范的编码习惯,一旦使了Lock,要充分考虑到可能出现的报错情况,所以一般编码会这样写try...catch...fianlly

public class LockFairThread implements Runnable{

    //创建公平锁
    private static ReentrantLock lock = new ReentrantLock(true);

    @Override
    public void run() {
        lock.lock();
        try{
            System.out.println(Thread.currentThread().getName() + "获得锁");
        }catch (Exception e){
            System.out.println("异常相关提示");
        }finally {
            lock.unlock();
        }
    }

}

常见的锁的概念

原文:https://www.cnblogs.com/mzdljgz/p/11630576.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!