java并发编程之synchronized

java的内置锁:每个java对象都可以用做一个实现同步的锁,这些锁成为内置锁。线程进入同步代码块或方法的时候会自动获得该锁,在退出同步代码块或方法时会释放该锁。获得内置锁的唯一途径就是进入这个锁的保护的同步代码块或方法。

java内置锁是一个互斥锁,这就是意味着最多只有一个线程能够获得该锁,当线程A尝试去获得线程B持有的内置锁时,线程A必须等待或者阻塞,知道线程B释放这个锁,如果B线程不释放这个锁,那么A线程将永远等待下去,也就是发生死锁。

 

synchronized:

synchronized是java的一个关键字,其意思是同步,是解决java并发编程的一大杀器。

一般来说,synchronized有以下两种使用方法:

  • 加在方法的描述上,使方法称为同步方法,例如:
public  synchronized void tests(){}

当非静态方法被标识为同步方法后,相当于给该方法加上了一个对象锁,也就是说,只有持有该对象锁的线程才能进入该方法内,执行方法体。

既然是对象锁,呢么不同对象自然拥有不同的对象锁,也就是说,当多个线程访问同一个对象的该同步方法时,会产生线程互斥,而如果多个线程访问不同对象内的该同步方法时,synchronized是无法让线程出现互斥情况的。

当一个类里有多个方法被标识为同步方法时,因为一个对象只有一个对象锁,所以当其中一个同步方法的对象锁被获取时,其他线程无法通过同一对象执行其其他的同步方法,因为该对象所有同步方法的对象锁都是同一把,也只有一把。

 

public   synchronized static void tests(){}

当静态方法被标识为同步方法后,相当于给改方法上了一个类锁,也就是说,只有持有该类锁的线程才能进入该方法内,执行方法体。

既然是类锁,呢么不同类有不同的类锁,一个类就只有一个类锁了,也就是说,当多个线程访问类中的静态同步方法时,会发生线程互斥,互斥结果与是否通过一个对象访问的无管,因为这里的锁是类锁。而当多个线程访问类中的静态同步方法和非静态同步方法时,他们之间是不会互斥的,因为它们的锁不同,一个获取到的是类锁,一个获取到的是对象锁。

 

  • 加在一个代码块上,形成同步代码块:

 

synchronized (this) {}

如上图写法,括号中间写this,就是指获取该类对象的对象锁,就像非静态同步方法,只不过方法的同步范围是整个方法体,而这个的同步范围是代码块内部。同理,如果一个类中有多个同步代码块,和多个同步非静态方法,只要其中一个的对象锁被取走,其他所有都无法执行,因为都是一个锁。当然,括号内也可以填入其他对象,这样一来该同步块的锁就是其他对象的锁了。

在使用时,务必判断清楚锁是否一致,不然无法正确发挥synchronized的作用

 

使用:

在保证执行结果正确的情况下,同步的范围越小越好,因为同步是会消耗执行性能的,也就是会消耗比不同步更多的时间,所以同步范围越大,效率越低。比如当你想吧一个方法改为同步方法时,请先确定,是否真的有必要将整个方法体同步,是否可以通过将方法体中的核心并发代码化为同步代码块来解决同步问题。

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值