http://www.cnblogs.com/paddix/p/5367116.html
syschronized的使用
(1)确保线程互斥的访问同步代码
(2)保证共享变量的修改能够及时可见
(3)有效解决重排序问题
从语法上讲,Synchronized总共有三种用法:
(1)修饰普通方法
4 public synchronized void method1(){
5 System.out.println(“Method 1 start”);
6 try {
7 System.out.println(“Method 1 execute”);
8 Thread.sleep(3000);
9 } catch (InterruptedException e) {
10 e.printStackTrace();
11 }
12 System.out.println(“Method 1 end”);
13 }
14
(2)修饰静态方法
public static synchronized void method1(){
5 System.out.println(“Method 1 start”);
6 try {
7 System.out.println(“Method 1 execute”);
8 Thread.sleep(3000);
9 } catch (InterruptedException e) {
10 e.printStackTrace();
11 }
12 System.out.println(“Method 1 end”);
13 }
(3)修饰代码块
4 public void method1(){
5 System.out.println(“Method 1 start”);
6 try {
7 synchronized (this) {
8 System.out.println(“Method 1 execute”);
9 Thread.sleep(3000);
10 }
11 } catch (InterruptedException e) {
12 e.printStackTrace();
13 }
14 System.out.println(“Method 1 end”);
15 }
syschronized的原理
4 public void method() {
5 synchronized (this) {
6 System.out.println(“Method 1 start”);
7 }
8 }
反编译以上代码得
monitorenter :
每个对象有一个监视器锁(monitor)。当monitor被占用时就会处于锁定状态,线程执行monitorenter指令时尝试获取monitor的所有权,过程如下:
1、如果monitor的进入数为0,则该线程进入monitor,然后将进入数设置为1,该线程即为monitor的所有者。
2、如果线程已经占有该monitor,只是重新进入,则进入monitor的进入数加1.
3.如果其他线程已经占用了monitor,则该线程进入阻塞状态,直到monitor的进入数为0,再重新尝试获取monitor的所有权。
monitorexit:
执行monitorexit的线程必须是objectref所对应的monitor的所有者。
通过这两段描述,我们应该能很清楚的看出Synchronized的实现原理,
Synchronized的语义底层是通过一个monitor的对象来完成,其实wait/notify等方法也依赖于monitor对象,这就是为什么只有在同步的块或者方法中才能调用wait/notify等方法,否则会抛出java.lang.IllegalMonitorStateException的异常的原因。
syschronized 与 lock(重入锁ReenTrantLock)
https://www.cnblogs.com/iyyy/p/7993788.html
1.首先synchronized是java内置关键字,在jvm层面,Lock是个java类;
2.synchronized无法获得锁的状态,因此会自动释放锁。(a 线程执行完同步代码会释放锁 ;b 线程执行过程中发生异常会释放锁),Lock需要在finally中调用Unlock()手工释放。
3.用synchronized关键字的两个线程1和线程2,如果当前线程1获得锁,线程2线程等待。如果线程1阻塞,线程2则会一直等待下去,而Lock锁就不一定会等待下去,如果尝试获取不到锁,线程可以不用一直等待就结束了;
4.synchronized的锁可重入、不可中断、非公平,而Lock锁可重入、可中断、可公平、绑定多个Condition.(两者皆可重入)
重入:可以再进入的锁。同一个线程每次进入一次,锁的计数器都自增1,所以要等到锁的计数器下降为0时才能释放锁。
等待可中断:在持有锁的线程长时间不释放锁的时候,等待的线程可以选择放弃等待. tryLock(long timeout, TimeUnit unit)
公平锁按照申请锁的顺序来一次获得锁称为公平锁.
绑定多个Condition 通过多次newCondition可以获得多个Condition对象,可以简单的实现比较复杂的线程同步的功能.通过await(),signal();
5.Lock锁适合大量同步的代码问题,synchronized锁适合代码少量的同步问题。