1、多线程的基本知识java
1.1进程与线程的介绍多线程
程序运行时在接口的方式性能
1.4 JAVA同步 synchronized关键字spa
加同步格式:线程
synchronized( 须要一个任意的对象(锁) ){对象
代码块中放操做共享数据的代码}接口
synchronized是java中的一个关键字,也就是说是Java语言内置的特性。若是一个代码块被synchronized修饰了,当一个线程获取了对应的锁,并执行该代码块时,其余线程便只能一直等待,等待获取锁的线程释放锁,而这里获取锁的线程释放锁只会有两种状况:进程
1.获取锁的线程执行完了该代码块,而后线程释放对锁的占有资源
2.线程执行发生异常,此时JVM会让线程自动释放锁。同步
因此synchronized等待线程能无期限地等待下去:这是一个致命的缺点
因此引进了Lock解决这个问题。
1.5 lock
1.5.1Lock于 Lock和synchronized的选择
1)Lock是一个接口,而synchronized是Java中的关键字,synchronized是内置的语言实现;
2)synchronized在发生异常时,会自动释放线程占有的锁,所以不会致使死锁现象发生;而Lock在发生异常时,若是没有主动经过unLock()去释放锁,则极可能形成死锁现象,所以使用Lock时须要在finally块中释放锁;
3)Lock可让等待锁的线程响应中断,而synchronized却不行,使用synchronized时,等待的线程会一直等待下去,不可以响应中断;
4)经过Lock能够知道有没有成功获取锁,而synchronized却没法办到。
5)Lock能够提升多个线程进行读操做的效率。
在性能上来讲,若是竞争资源不激烈,二者的性能是差很少的,而当竞争资源很是激烈时(即有大量线程同时竞争),此时Lock的性能要远远优于synchronized。因此说,在具体使用时要根据适当状况选择。
1.5.2 Lock接口中每一个方法的使用:
lock()、tryLock()、tryLock(long time, TimeUnit unit)、lockInterruptibly()是用来获取锁的。
unLock()方法是用来释放锁的。
1.5.3 四个获取锁方法的区别:
lock()方法是日常使用try{}catch{}块中进行,而且将释放锁的操做放在finally块中进行,以保证锁必定被被释放,防止死锁的发生。
tryLock()方法是有返回值的,它表示用来尝试获取锁,若是获取成功,则返回true,若是获取失败(即锁已被其余线程获取),则返回false,也就说这个方法不管如何都会当即返回。在拿不到锁时不会一直在那等待。
tryLock(long time, TimeUnit unit)方法和tryLock()方法是相似的,只不过区别在于这个方法在拿不到锁时会等待必定的时间,在时间期限以内若是还拿不到锁,就返回false。若是若是一开始拿到锁或者在等待期间内拿到了锁,则返回true。
lockInterruptibly()方法比较特殊,当经过这个方法去获取锁时,若是线程正在等待获取锁,则这个线程可以响应中断,即中断线程的等待状态。也就使说,当两个线程同时经过lock.lockInterruptibly()想获取某个锁时,倘若此时线程A获取到了锁,而线程B只有等待,那么对线程B调用threadB.interrupt()方法可以中断线程B的等待过程。
注意,当一个线程获取了锁以后,是不会被interrupt()方法中断的。
所以当经过lockInterruptibly()方法获取某个锁时,若是不能获取到,只有进行等待的状况下,是能够响应中断的。
而用synchronized修饰的话,当一个线程处于等待某个锁的状态,是没法被中断的,只有一直等待下去。ReentrantLock
直接使用lock接口的话,咱们须要实现不少方法,不太方便,ReentrantLock是惟一实现了Lock接口的类,而且ReentrantLock提供了更多的方法,ReentrantLock,意思是“可重入锁”。