对于多线程(并发)和Spring Boot这两块在同步进行学习中,在看到使用synchronized关键字使操做同步时,看到和C#中不同的东西,因此这里呢,就深刻学习了下,如有错误之处,还望指正。java
咱们知道因为并发会致使线程不安全的问题,此时咱们手段之一采起线程同步,也就是说使得全部并发线程在执行中保持同步的过程,当方法声明为同步时,传递到同步块中的对象称之为监视器或锁定对象,若是有另一个线程也在执行该同步方法,那么该线程将被阻塞,直到线程释放该监视器或锁定对象。咱们在类中已定义的方法或块上使用synchronized关键字,同时synchronized关键字不能与类定义中的变量或属性一块儿使用。安全
所谓的对象级别锁,也就是针对非静态方法执行同步块锁定,那么同步块中的监视器或锁定对象则是基于对象实例,有以下三种形式多线程
class Test { public synchronized void LockMethod() { } }
或者并发
class Test { public void LockMethod() { synchronized(this) { } } }
或者学习
class Test { private final Object lock = new Object(); public void LockMethod() { synchronized (lock) { } } }
若在同步方法中存在静态数据,为保持静态数据线程安全,咱们则需使用类级别锁,这意味着,若是在运行时有多个实例的Test,则一次只能在一个实例中的一个线程上执行一个线程LockMethod(),而全部其余实例将被其余线程锁定。针对类级别锁,那么同步块中监视器或锁定对象有以下三种形式:this
class Test { public synchronized static void LockMethod() { } }
或spa
class Test { public void LockMethod() { synchronized (Test.class) { } } }
或线程
class Test { private final static Object lock = new Object(); public void LockMethod() { synchronized (lock) { } } }
在这里我主要是看到了上述第二种形式中所使用的锁定对象,因为java和C#语法大多类似,可是这在C#中找不到可对比的东西,我不明白这究竟是什么个意思,因此就深刻看了些,本觉得能够直接查看源码,然而并无任何反应,看来就是Java中自然存在的了,我去打印发现和获取实例的类名的结果是同样的,咱们将这种状况翻译为className.class,这究竟是什么意思呢?为什么上述第二种形式就是类级别锁定从而保证线程安全了呢?翻译
System.out.println(Test.class.toString()); System.out.println(new Test().getClass());
因而乎我想到看一下所购买的《深刻理解Java虚拟机》中对于类加载原理的解释,结果发现:在类加载时机的第一阶段也就是加载阶段,虚拟机会完成3件事情,其中最后一件事情则是在内存中生成一个对应类的java.lang.Class对象,做为方法区这个类的各类数据的入口。换句话说,每一个类在JVM中有且只会有惟一的一个java.lang.Class对象实例,因此我大胆猜想className.class就是获取java.lang.Class对象惟一实例的引用,如此一来就保证始终只有一个线程可以进入同步块。code
本节咱们经过对关键字synchronized实现线程同步作了详细了解,其实并不难,这里我想表达的是看到和C#中不同的东西,也就是className.class具体是什么意思,同时在用java实现单例模式中也有这种状况,因此详细学习了下,也作个备忘录,可能对大部分学java的童鞋而言确实很简单,我仍是处于初级阶段,也是在一步步深刻的学习。