线程和锁2

一.synchronized和Lock:

synchronized:有一个共享资源,我们只允许一次一个线程访问它。把所有能访问该资源的方法都封装到一个类中,然后把这些方法全都加上synchronized关键字,如果这时候有一个线程正在调用一个该关键字标记的方法,那么当这个线程从该方法返回之前,其他所有要调用该关键字所标记的方法的线程都会被阻塞。

 

https://www.jianshu.com/p/b1581c35c881    //这个网址讲锁讲的特别好

lock:

 

 

synchronied和lock的比较:

再解决以后

synchronized的缺陷:

  有两种情况可以让一个执行synchronized修饰的方法的线程退出,一是执行完毕,二是线程执行发生异常,JVM会让线程自动释放锁。。。。。。所以如果这个线程由于等待IO或者其他情况(比如sleep方法)被阻塞而又没有释放锁,那么其他想操作这个锁的线层就要一直等下去。  再比如“读操作”,这个操作是可以多个线程同时执行的。你synchronized关键字就做不到,Lock可以

 

Lock必须手动释放,否则容易造成死锁,而synchronized关键字不需要手动释放,执行完他自己就释放了

 

Lock是个接口 而synchronized是java内置的关键字

 

通过Lock可以获取有没有获得锁,而synchronized则不能

 

Lock可以提高多个线程获得锁的效率

 

 

 

 

 

 

 

 

 

 

 

 

二.线程的五大状态:

1.新建

2.就绪

3.运行

4.阻塞

5.死亡

 

三:java当中的死锁举例:

public class DeadLockTest
{
    private static Object A = new Object(), B = new Object();

    public static void main(String[] args)
    {
        new Thread(() -> {
            System.out.println("线程1开始执行...");
            synchronized (A)
            {
                try
                {
                    System.out.println("线程1拿到A锁");
                    //休眠两秒让线程2有时间拿到B锁
                    Thread.sleep(2000);
                } catch (Exception e)
                {
                    e.printStackTrace();
                }
                synchronized (B)
                {
                    System.out.println("线程1拿到B锁");
                }
            }
        }).start();
        
        new Thread(() -> {
            System.out.println("线程2开始执行...");
            synchronized (B)
            {
                try
                {
                    System.out.println("线程2拿到B锁");
                    //休眠两秒让线程1有时间拿到A锁
                    Thread.sleep(2000);
                } catch (Exception e)
                {
                    e.printStackTrace();
                }
                synchronized (A)
                {
                    System.out.println("线程2拿到A锁");
                }
            }
        }).start();
        
    }
}

 

 

 

四.violate关键字

https://blog.csdn.net/yinbucheng/article/details/71305951

 

 

五:乐观锁和悲观锁

悲观锁:总是假设最坏的情况,认为每次拿数据都会有别人过来修改,所以每次拿数据都会加锁,等自己操作完成后才会释放,然后给其他线程机会,比如syncronized就是悲观锁

乐观锁:总是假设最好的情况,每次更新的时候都认为别人不会修改,所以都不加锁,但是更新的时候会判断一下在此期间别人有没有去更新这个数据,可以使用CAS算法来实现

 

两种锁的应用场景:

从上面对两种锁的介绍,我们知道两种锁各有优缺点,不可认为一种好于另一种,像乐观锁适用于写比较少的情况下(多读场景),即冲突真的很少发生的时候,这样可以省去了锁的开销,加大了系统的整个吞吐量。但如果是多写的情况,一般会经常产生冲突,这就会导致上层应用会不断的进行retry,这样反倒是降低了性能,所以一般多写的场景下用悲观锁就比较合适。

 

 

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值