各种锁的理解

公平锁非公平锁

区别:是否可以插队(默认都是非公平锁)
设置公平锁new ReentrantLock(ture)

可重入锁(递归锁)

可以理解为:拿到外面的锁就会获得里面的锁

//Synchronized
public class Demo1 {
    public static void main(String[] args) {
        Phone phone = new Phone();
        new Thread(() -> {
            phone.sms();
        },"A").start();
        new Thread(() -> {
            phone.sms();
        },"B").start();
    }
}
class Phone {
    public synchronized void sms() {
        System.out.println(Thread.currentThread().getName()+"sms");
        call();
    }
    public synchronized void call() {
        System.out.println(Thread.currentThread().getName()+"call");
    }
}
//lock
public class Demo2 {
    public static void main(String[] args) {
        Phone phone = new Phone();
        new Thread(() -> {
            phone.sms();
        },"A").start();
        new Thread(() -> {
            phone.sms();
        },"B").start();
    }
}
class Phone2 {
    Lock lock = new ReentrantLock();
    public  void sms() {
        lock.lock();
        try {
            System.out.println(Thread.currentThread().getName()+"sms");
            call();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }
    public  void call() {
        try {
            System.out.println(Thread.currentThread().getName()+"call");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }
}

自旋锁(spinlock)

写一个自旋锁

//自旋锁
public class SpinlockDemo {
    AtomicReference<Thread> atomicReference = new AtomicReference<>();
    //加锁
    public void myLock() {
        Thread thread =Thread.currentThread();
        System.out.println(thread.getName()+"===> mylock");
        while (!atomicReference.compareAndSet(null, thread)) {
            System.out.println(thread.getName());
        }
    }

    //解锁
    public void myUnLock() {
        Thread thread =Thread.currentThread();
        System.out.println(thread.getName()+"===> myunlock");
        atomicReference.compareAndSet(thread, null);
    }
}

测试

   public static void main(String[] args) throws InterruptedException {
        SpinlockDemo lock = new SpinlockDemo();
        new Thread(() -> {
                lock.myLock();
            try {
                TimeUnit.SECONDS.sleep(3);
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                lock.myUnLock();
            }
        },"T1").start();
        TimeUnit.SECONDS.sleep(1);
        new Thread(() -> {
            lock.myLock();
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                lock.myUnLock();
            }
        },"T2").start();
    }

乐观锁

自我理解:为了提高并发效率,获得更高的吞吐量,默认不会出现冲突,在读取时做个标记,更改时根据标记判断数据是否更改,更改则回滚,未更改在更改。(不会一直占用直到提交时才去锁定)
乐观并发控制的事务包括以下阶段:

  1. 读取:事务将数据读入缓存,这时系统会给事务分派一个时间戳。
  2. 校验:事务执行完毕后,进行提交。这时同步校验所有事务,如果事务所读取的数据在读取之后又被其他事务修改,则产生冲突,事务被中断回滚。
  3. 写入:通过校验阶段后,将更新的数据写入数据库。

悲观锁

悲观锁就是在操作数据时,认为此操作会出现数据冲突,所以在进行每次操作时都要通过获取锁才能进行对相同数据的操作。
共享锁
  共享锁指的就是对于多个不同的事务,对同一个资源共享同一个锁。(悲观锁的一种)
排它锁
排它锁与共享锁相对应,就是指对于多个不同的事务,对同一个资源只能有一把锁。
与共享锁类型,在需要执行的语句后面加上for update就可以了

行锁

行锁,由字面意思理解,就是给某一行加上锁,也就是一条记录加上锁。

表锁

表锁,和行锁相对应,给这个表加上锁。

死锁问题

死锁是什么
两个对象互相争抢对方的锁
如:

public class DeadLockDemo {
    public static void main(String[] args) {
        String lockA = "lockA";
        String lockB = "lockB";

        new Thread(new MyThread(lockA,lockB),"T1").start();
        new Thread(new MyThread(lockB,lockA),"T2").start();
    }
}
class MyThread implements Runnable{
    private String lockA;
    private String lockB;

    public MyThread(String lockA, String lockB) {
        this.lockA = lockA;
        this.lockB = lockB;
    }
    @Override
    public void run() {
        synchronized (lockA){
            System.out.println(Thread.currentThread().getName()+"lock:"+lockA+"=>get"+lockB);
            try {
                TimeUnit.SECONDS.sleep(2);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            synchronized (lockB){
                System.out.println(Thread.currentThread().getName()+"lock:"+lockB+"=>get"+lockA);
            }
        }
    }
}

解决问题
1、使用jps -l定位进程号
2、使用jstack 进程号找到死锁问题

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值