线程笔记

一、Synchronized的两个用法
(一)对象锁:包括方法锁(默认锁对象为this当前实例对象)和同步代码块锁(自己指定锁对象)
(二)类锁:指synchronize修饰静态的方法或指定锁为Class对象 

类锁的用法:
1、概念:Java类可能有很多个对象,单只有一个Class对象

2、形式1:synchronize加载static方法上

3、形式2:synchronize(*.class) 代码块


二、多线程访问同步方法的7种情况(面试常考)
1、两个线程同时访问一个对象的同步方法
解答:一个线程执行完释放锁以后,另一个线程才可以获取锁并进行执行(串行)
2、两个线程访问的是两个对象的同步方法
解答:两个线程同时开始同时结束(并行),两者不互相干扰
3、两个线程访问的是synchronize的静态方法
解答:两个线程会一个执行完才进行第二个执行(串行)
4、同时访问同步方法与非同步方法
解答:非同步方法不受影响,两者会同时进行(并行)
5、访问同一个对象的不同的普通同步方法
解答:会出现串行的情况,即一个线程执行完毕后,才会执行另一个线程。因为虽然两个被访问的方法都被synchronize修饰,但是其实访问的都是同一个this锁,他们共用了一个锁,所以是串行。
6、同时访问静态synchronize和非静态synchronize方法
解答:出现并行,因为静态的锁对象是Class,而非静态的锁对象是实例化对象所以互不干扰。(并行)
7、方法抛异常后,会释放锁
解答:抛异常后,jvm会帮你释放锁,这样其余线程就可以获取锁了。

7种情况总结:3点核心思想
1、一把锁只能同时被一个线程获取,没有拿到锁的线程必须等待(对应第1、5种情况)
2、每个实例都对应有自己的一把锁,不同实例之间互不影响;例外:锁对象是*.class以及synchronize修饰的是static方法的时候,所有对象共用一把类锁(对应第2、3、4、6种情况)
3、无论是方法正常执行完毕或者方法抛出异常,都会释放锁(对应第7种情况)

注意:不同对象产生的线程,只会访问自身对象的线程run方法
例如:(1) A a = new A();
Thread t1 = new Thread(a);
Thread t2 = new Thread(a);
t1.start();
t2.start();
因为两个线程都是由对象a产生的,所以线程启动时会共同抢占a对象中run方法
(2) A a1 = new A();  A a2 = new A();
Thread t1 = new Thread(a1);
Thread t2 = new Thread(a2);
t1.start();
t2.start();
因为两个线程是由不同的对象产生的,由a1、a2产生的所以在线程启动时会抢占各自对象中的run方法。


synchronize可重入性:指的是同一线程的外层函数获得锁之后,内层函数可以直接再次获取该锁
好处:避免死锁。提升封装性
粒度:线程而非调用。
情况1:证明同一个方法是可重入的
情况2:证明可重入不要求是同一个方法
情况3:证明可重入不要求是同一个类中

synchronize不可中断:一旦这个锁已经被别人获得了,如果我还想获得,我只能选择等待或者阻塞,直到别的线程释放锁,否则一直等下去
 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值