接上文。
一:多线程同步
当使用多线程访问一个资源的时候,容易出现线程安全的问题。比如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()需要咋同步控制方法或者同步语句块中使用。