在介绍Synchrinized以前,咱们先来了解一下并发的相关概念。编程
并发: 同一时间段,多个任务都在执行 (单位时间内不必定同时执行);在同一时刻只会有一条指令执行,可是多个指令被快速轮换执行,这个切换的时间很是短以致于咱们不用去考虑它,这就是并发的基本含义。安全
而多线程正是咱们能够完成并发的很重要的执行手段。如今的系统动不动就要求百万级的并发量,而多线程并发编程正是开发高并发系统的基础,利用好多线程的特性能够大大的提升咱们的系统运行的效率。并且当今正值多核CPU时代,多线程也能够提升咱们CPU的利用效率,最大化的利用咱们现有的资源。bash
上文说了多线程这么多的好处,那么它有什么缺点呢?多线程
咱们在多线程的环境下,系统的执行顺序并非由咱们控制的,执行的线程就可能随时切换到其余线程中执行。这就可能会形成一些安全性的问题。 好比小A小B两我的同时在抢票(仅剩一张),小A买票的线程先执行,判断 num 是否大于0(如今 num =1),而后 num--。执行完这个操做以后,小B线程也开始执行,也开始判断 num 是否大于0,由于小A更新的num还没有更新到主存中,小B的工做空间的 num 值仍是大于1,因此也执行 num--。并发
这个时候问题就出现了,只有一张票,作了两次 num--,最后num的值为-1系统就出现了错误。那么如何防止这种现象出现呢?这里咱们就引入了 Synchronzied。高并发
Synchronized 关键字解决的是多个线程之间访问资源的同步性,Synchronized 关键字能够保证被它修饰的方法或者代码块在任意时刻只能有一个线程执行。spa
还用刚才的买票问题举例,下面是代码线程
while (true) {
synchronized (obj) {
if (ticket > 0) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + ":" + ticket--);
}
}
}
复制代码
此次咱们使用了 Synchronized 来对整个 if 语句进行修饰,就保证了if语句的原子性,只有当整个 if 语句的代码执行完毕的时候,才会释放锁,咱们也就很容易的解决了买票的问题。code
下面咱们来介绍一下 Synchronzied 的主要使用方式对象
synchronized 关键字最主要的三种使用方式:
* 修饰实例方法: 做用于当前对象实例加锁,进入同步代码前要得到当前对象实例的锁
* 修饰静态方法: 也就是给当前类加锁,会做用于类的全部对象实例,由于静态成员不属于任何一个实例对象,是类成员( static代表这是该类的一个静态资源,无论new了多少个对象,只有一份)。因此若是一个线程A调用一个实例对象的非静态 synchronized 方法,而线程B须要调用这个实例对象所属类的静态 synchronized 方法,是容许的,不会发生互斥现象,由于访问静态 synchronized 方法占用的锁是当前类的锁,而访问非静态 synchronized 方法占用的锁是当前实例对象锁。
* 修饰代码块: 指定加锁对象,对给定对象加锁,进入同步代码库前要得到给定对象的锁。
这些就是今天介绍 Synchronized 的所有内容,从此我也会持续在个人专栏中更新更多有价值的内容,欢迎关注。