1.Synchronized
1.1 加了synchronized的字节码指令和java源代码
synchronized(new Object()){ int a = 1;int b = 2; System.out.println(add(a,b)); }
由上图:被Synchronized修饰过的代码块,会生成monitorenter(监视器)字节码指令和monitorexit(监视器退出)字节码指令,当虚拟机执行到监视器指令的时候,就要去尝试去获取这个对象的锁,如果这个对象没有锁定,或者是当前线程已经获取了这个对象的锁(因为是可重入锁),就把锁的计数器+1,如果执行到监视器退出指令时候,就把锁的计数器-1。当计数器变为0的时候,就相当于这把锁被释放了,大家可以竞争。
1.2 Synchronized到底锁主了什么?
1.Synchronized(Object、this)这样指定了对象的锁的就是这个对象
2.在非静态方法上加上Synchronized相当于每个对象都有一把单独的锁
,假设创建对象p1,p2 如果p1执行了add方法占用了锁,但是占用的只是p1对象的锁,在另外一个线程中不影响p2继续执行add方法。
public synchronized int add(int a,int b)
3.在静态方法上加锁
相当于锁住了这个类,所有的实例共享一把锁,p1执行add方法占用了锁,在另外一个线程p2如果也想要add方法,执行同样需要等待
public synchronized static int add(int a,int b)
1.3可重入的特征
Synchronized是一个可重入锁,为了解决锁死自己的情况,来看示例:
Object o = new Object(); synchronized (o){ //计数器+1变为1 synchronized (o){//计数器+1变为2 System.out.println("执行么? "); }//计数器-1变为1 }//计数器-1变为0 此时别的线程能够抢占
第一个synchronized已经占用到o这把锁了,第二个还能拿么,答案是可以的,不然很容易锁死。代码正常执行。