【Java多线程】(二)多线程同步

接上文。


一:多线程同步

当使用多线程访问一个资源的时候,容易出现线程安全的问题。比如A、B两个线程模拟两个用户银行转账业务。刚开始两人各有1000元。首先A、查询自己余额为1000,然后提现100,并把余额修改为900。假如提现是一个非常耗时的操作,在完成这个操作之前,B给A转了账100。转完账以后将A的余额修改为1100。此时A提现完成,并将余额修改为900。可见这个结果时不合理的。这就是一个多线程同时访问的安全问题。这个时候就需要同步机制。

解决多线程的方式其实就是枷锁。一次只能允许一个线程执行某段代码,或者读取修改某个变量。

方法一:synchronized关键字。

在Java语言中,每个对象都有一个对象锁,该锁表明对象在任何时候只允许一个线程所拥有。当线程执行synchronized代码时,首先需要获取这个锁,当代码执行结束之后释放锁。从而使得每次只有一个线程访问执行代码,从而不会出现多线程安全问题。

方法二: Lock关键字

JDK5之后添加了Lock接口,以及它的一个实现类ReentrantLock(重入锁)。也可以实现方法一的功能。主要有一下几个关键方法:

1.lock()。以阻塞的方式获取锁。即如果获取锁,返回。获取不到锁,等待,直到获取锁。

2.tryLock()。字面意思,尝试性获取锁。尝试获取一下锁,成功返回true;否则,返回false。

3.lockInterruptibly()。类似1,不同的时,如果获取不到锁,就等待,但是也能被打断。

二:Synchronized与Lock区别

1:用法不同。

Synchronized可以加在方法或者代码块上,托管给jvm执行,但是lock必须显示的指定起始和终止位置,锁定是通过代码完成。

2. 性能不一样

在资源竞争不激烈的时候,synchronized性能好。激烈的时候,lock的实现类reentrantLock性能基本保持不变,synchronized性能下降很快

3. 锁机制不一样

Synchronized获得多个锁的时候必须以相反的顺序释放,并且是自动的解锁,不会引发死锁。Lock必须人工手动在finally块释放锁。否则会引起死锁。

三:sleep()与wait()区别

1.原理不相同

sleep()是Thread的静态方法,是线程用来控制自身流程的。他会暂停当前线程的执行,进行休眠,并把执行的机会让给其他线程。当休眠时间到了,便会自动醒来。而wait()方法则不一样,是Object类中的方法,用于进城之间的通信。使得当前线程停止执行,直到其他线程执行notify()或者是notifyAll()方法,才会唤醒。当然,也可以给自己设定一个醒来的时间。

2.处理机制不一样。

sleep()是让线程暂停一段时间,并不释放锁,且不涉及线程之间的通信。但是wait()方法则是直接释放锁,别的线程可以获取锁。

3.作用域不一样。

sleep()可以放在任何地方,wait()需要咋同步控制方法或者同步语句块中使用。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值