用一个数据在不同的线程进行同时读写的过程中会出各种各样的问题,为了保证线程安全性,就要加锁,但锁太多效率又会降低。所以我们为了安全要放锁,为了性能要把锁的力度变细(会导致死锁)。
假如说第一个人都在from.getAmount()的时候获取了10元的数据,然后还没来得急存进5元,第二个人又from.getAmount()获取到10元,然后两个人都转了过去。最后,明明转了两次5元,却只减了一次5元。
因此要加锁:
把from和to都锁住,在第一个人转5元的时候,在它转完之前,第二个人是进不来的,就不会同时去拿走5元,
symchronized是针对对象的,一个针对from一个针对to,锁住的是代码段,同一个对象只能有一个执行.
1、 在任何地方都可以线程切换,甚至在一句语句中间
2、 要尽力设想对自己最不利的情况
symchronized(from) ——别的线程在等待from
symchronized(to) ——别的线程已经锁住了to
可能死锁:transfer(a,b,100)和transfer(b,a,100)同时进行
死锁条件,必须同时满足:
1、 互斥等待(有一段代码块,或者一些操作,同时只能有一个人做,抢到锁的人先做,没抢到的必须等待前一个做完才能做,也就是首先得有锁)
2、 hold and wait(拿着一个锁却在等待另一个锁)
3、 循环等待(拿着b的锁等待a,另外一个人拿着a的锁等待b,有的等待会有超时的,死锁超时会自动解掉。)
4、 无法剥夺的等待
死锁防止(挑取死锁四个条件的任何一个进行破除)
破除互斥等待 —— 一般无法破除(要保证线程安全,有些东西就是必须上锁)
破除hold and wait —— 一次性获取所有资源
破除循环等待 —— 按顺序获取资源
破除无法剥夺的等待 —— 加入超时