在并发编程中存在线程安全问题,主要缘由有:存在共享数据,多线程共同操做共享数据。关键字synchronized能够保证在同一时刻,只有一个线程能够执行某个方法或某个代码块,同时synchronized能够保证一个线程的可见性java
利用锁的机制来实现同步的(解决数据点不一致性 JMM)编程
private static int m = 0; private Object obj = new Object(); public void test1() { try { synchronized (obj) { TimeUnit.MINUTES.sleep(2); m++; } } catch (InterruptedException e) { e.printStackTrace(); } }
锁效果与同步静态方法同样,都是类级别的锁,同时只有一个线程能访问带有同步类锁的方法。缓存
public class synchronizedDemo { private static int m = 0; public void test2() { try { synchronized (synchronizedDemo.class) { TimeUnit.MINUTES.sleep(2); m++; } } catch (InterruptedException e) { e.printStackTrace(); } } }
与同步块的用法一致,表示锁住整个当前对象实例,只有获取到这个实例的锁才能进入这个方法。安全
private static int m = 0; public void test2() { try { synchronized (this) { TimeUnit.MINUTES.sleep(2); m++; } } catch (InterruptedException e) { e.printStackTrace(); } }
可经过工具jconsole和jstack去观察synchronized的底层以及线程状况。多线程
方法锁就是由关键字ACC_SYNCHRONIZED实现是否互斥方法,并发
monitor:在jvm规范中每一个对象和类在逻辑上都是和一个监视器(monitor)相关联的,为了实现监视器的排他性监视能力,JVM为每个对象和类都关联一个锁,锁住了一个对象,这就是得到对象相关联的监视器。
实现原理:某一个线程占有这个对象的时候,首先monitor的计数器是否是0,若是是0表示尚未线程占有这个时候线程占有这个对象,而且对这个对象的monitor+1;若是不为0表示这个对象已经被其余线程占有,这个线程等待。当线程释放占有权的时候monitor-1。
注:同一个线程能够对同一个对象屡次加锁,+1,+1,重入锁jvm