乐观锁(Pessimistic)与悲观锁(Optimistic)

Java 专栏收录该内容
10 篇文章 0 订阅

结论

其实乐观锁(Optimistic)和悲观锁是对读和写而言的,悲观锁(Pessimistic)是读有优势,而乐观锁锁则是写有优势.
所以乐观锁时候写少的情况,悲观锁时候读少的情况.

悲观锁

悲观锁是指在用读取锁锁定一块代码的时候,另一个读取锁依然可以进入该代码块,而写锁不可以进入.在用写锁锁定一段代码的时候,读锁和写锁都不能进入该代码块.

乐观锁

乐观锁其实就是写锁优先机制,读锁在锁定某一代码块的时候,如果没有写锁竞争,那么就会获得该锁的权限,如果进行锁定的时候发现有写锁正在竞争,那么就会抛出例外,需要重新操作进行锁定.竞争标志则是
long stamp = lock.tryOptimisticRead();//有竞争返回0
lock.validate(stamp);//有竞争返回true

以下是代码验证:

悲观锁示例

package Test;

import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

public class Main {
    public static void main(String[] args) {
        Pessimistic p = new Pessimistic();
        Thread t1=new Thread(()->{
            p.addSome();
        });
        Thread t2=new Thread(()->{
            p.getSome();
        });

        Thread t3=new Thread(()->{
            p.getSome();
        });

        t1.start();
        t2.start();
        t3.start();


    }

}


class Pessimistic{
    private ReadWriteLock lock = new ReentrantReadWriteLock();

    public void addSome() {
        lock.writeLock().lock();

        try {
            System.out.println("addSome方法被我锁啦,我要霸占这把锁2s钟");
            Thread.sleep(2000);
        }catch (Exception e) {
            // TODO: handle exception
            e.printStackTrace();
        }finally {
            lock.writeLock().unlock();
        }
    }


    public void getSome() {
        lock.readLock().lock();

        try {
            System.out.println("getSome方法被我锁啦,我要霸占这把锁2s钟");
            Thread.sleep(2000);
        }catch (Exception e) {
            // TODO: handle exception
            e.printStackTrace();
        }finally {
            lock.readLock().unlock();
        }
    }
}

/*-------------------------------------
结果:

addSome方法被我锁啦,我要霸占这把锁2s钟
//间隔两秒
getSome方法被我锁啦,我要霸占这把锁2sgetSome方法被我锁啦,我要霸占这把锁2s钟

情况2:
getSome方法被我锁啦,我要霸占这把锁2sgetSome方法被我锁啦,我要霸占这把锁2s钟
//间隔两秒
addSome方法被我锁啦,我要霸占这把锁2s钟
------------------------------------*/

乐观锁示例

package Test;

import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import java.util.concurrent.locks.StampedLock;

public class Main {
    public static void main(String[] args) {
        Optimistic p = new Optimistic();
        Thread t1=new Thread(()->{
            p.addSome();
        });
        Thread t2=new Thread(()->{
            p.getSome();
        });

        Thread t3=new Thread(()->{
            p.getSome();
        });

        t1.start();
        t2.start();
        t3.start();


    }

}


class Pessimistic{
    private ReadWriteLock lock = new ReentrantReadWriteLock();

    public void addSome() {
        lock.writeLock().lock();

        try {
            System.out.println("addSome方法被我锁啦,我要霸占这把锁2s钟");
            Thread.sleep(2000);
        }catch (Exception e) {
            // TODO: handle exception
            e.printStackTrace();
        }finally {
            lock.writeLock().unlock();
        }
    }


    public void getSome() {
        lock.readLock().lock();

        try {
            System.out.println("getSome方法被我锁啦,我要霸占这把锁2s钟");
            Thread.sleep(2000);
        }catch (Exception e) {
            // TODO: handle exception
            e.printStackTrace();
        }finally {
            lock.readLock().unlock();
        }
    }
}


class Optimistic{
    private StampedLock lock =new StampedLock();
    public void addSome() {
        long stamp=lock.writeLock();
        try {
            System.out.println("addSome方法被我锁啦,我要霸占这把锁2s钟");
            Thread.sleep(2000);
        }catch (Exception e) {
            // TODO: handle exception
            e.printStackTrace();
        }finally {
            lock.unlockWrite(stamp);
        }
    }


    public void getSome() {
        long stamp = lock.tryOptimisticRead();//如果有其他锁,戳记会为0
        try {
            if(!lock.validate(stamp)) {
                stamp=lock.readLock();
                System.out.println("getSome方法被我锁啦,我要霸占这把锁2s钟");
                Thread.sleep(2000); 
            }
        }catch (Exception e) {
            // TODO: handle exception
            e.printStackTrace();
        }finally {
            try {

                lock.unlockRead(stamp);
            }catch (Exception e) {
                // TODO: handle exception
                System.out.println("已经被write锁锁了");
            }
        }
    }
}


/*------------------------------------
结果
情况1://大多数情况
addSome方法被我锁啦,我要霸占这把锁2s钟
//间隔两秒钟
getSome方法被我锁啦,我要霸占这把锁2sgetSome方法被我锁啦,我要霸占这把锁2s钟


情况2:
已经被write锁锁了
addSome方法被我锁啦,我要霸占这把锁2sgetSome方法被我锁啦,我要霸占这把锁2s钟
------------------------------------*/
  • 0
    点赞
  • 0
    评论
  • 2
    收藏
  • 打赏
    打赏
  • 扫一扫,分享海报

©️2022 CSDN 皮肤主题:编程工作室 设计师:CSDN官方博客 返回首页

打赏作者

O欧阳O

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值