参考:https://www.cnblogs.com/dolphin0520/p/3923167.html
http://blog.csdn.net/luoweifu/article/details/46613015
1.sysnchronized
A. 无论synchronized关键字加在方法上还是对象上,如果它作用的对象是非静态的,则它取得的锁是对象;如果synchronized作用的对象是一个静态方法或一个类,则它取得的锁是对类,该类所有的对象同一把锁。
B. 每个对象只有一个锁(lock)与之相关联,谁拿到这个锁谁就可以运行它所控制的那段代码。C.静态代码块情况。例如,sysnchronized(obj){},当线程执行这块代码的时候,需要获取“obj”这个对象的锁,方可执行大括号里面的代码。所有我们需要判断的是,是否“obj”这个对象的锁被别的线程拿走了。
Integer obj=5;和Integer obj=555;这两种情况,如果两个或者多个线程去执行静态代码块结果是不一样的。Integer obj=5;绝对会等待锁,因为,这个对象始终是一个对象;Integer obj=555,一般不会等待,因为这个对象可能是多个不同的对象。
所有静态代码块我们需要关注的是obj,盯住它。
2.lock
lock是一个接口,synchronize是java语言内置的
A.synhronized能实现的lock都可以实现。
B.可以尝试获取锁,trylock方法。可以设置尝试的时间,如果获取不了,可以继续做其他事情,synchronized,要么获取执行,要么等待。lockInterruptibly()方法获取某个锁时,如果不能获取到,只有进行等待的情况下,是可以响应中断的,通过interrupt()方法。
C.的ReentrantReadWriteLock实现类,提供了读锁和写锁,获取写锁的的时候,线程相互不阻塞,写锁会,相当于是将一个锁分类了
D.lock需要手动是否锁,一般在finnally{释放锁}
E.某种程度上,两者原理一样,都要获取锁,才能够往下执行,所有要考虑多个线程执行到需要锁的时候,是不是同一个锁,是否还在别人手上。也就是要考虑锁的作用范围。例如下面的情况多个线程执行不会阻塞等待锁,因为这里的锁,每个线程执行都会产生一个新的锁,没有被别人得到的。
public void insert(Thread thread) { Lock lock = new ReentrantLock(); //注意这个地方 lock.lock(); try { System.out.println(thread.getName()+"得到了锁"); for(int i=0;i<5;i++) { arrayList.add(i); } } catch (Exception e) { // TODO: handle exception }finally { System.out.println(thread.getName()+"释放了锁"); lock.unlock(); } }