文章目录
前言
在工作中,如果你公司用得是老版本的JDK(这里说的老版本一般都是JDK1.6之前的版本,甚至1.6的也有些公司在大面积的使用),那肯定少不了synchronized的使用,如果不了解synchronized的一些原理的话,那么出现问题的时候就不能快速定位了和修复了。
本文主要讲述synchronized到底锁的是什么。
一、什么是synchronized,用来做什么的?
1. 定义
- 英文翻译:(使)同步,在时间上一致。
- 在JAVA中:
- 同步,也称为同步锁。
- 它的作用是保证在同一时刻,被修饰的代码块或方法只会有一个线程执行,以达到保证并发安全的效果。
- synchronized是JAVA中解决并发问题的一种常用的方法,也是最简单的一种方法。
- 在JDK1.5之前synchronized是一个重量级锁,相对于JUC中的Lock,它会显示比较笨重,随着1.6对其进行的各种优化后,它也不会显得那么重了。
2. 作用
- 原子性: 确保线程互斥地访问同步代码;
- 可见性: 多个线程访问一个资源时,该资源的状态、值信息等对于其他线程都是可见的。
- 有序性: 程序执行的顺序按照代码先后执行。(JAVA允许编译器和处理器对指令进行重排,但是指令重排并不会影响单线程的顺序,它影响的是多线程并发执行的顺序。)synchronized保证了每个时刻都只有一个线程访问同步代码块,也就确定了线程执行同步代码块是分先后顺序的,保证了有序性。
3. 如何使用
- 修饰方法
- 修饰静态方法
- 修饰代码块
代码如下:
// 修饰方法
public synchronized void add() {
// 方法逻辑代码
}
// 修饰静态方法
public static synchronized void sub() {
// 方法逻辑代码
}
// 修饰代码块
public void sale() {
Object obj = new Object();
// 修饰代码块
synchronized (obj) {
// 代码块
}
// 修饰代码块
synchronized (Person.class) {
// 代码块
}
}
二、synchronized锁的是什么
1. 锁当前实例对象
代码如下:
public class Phone {
public synchronized void sendMsg() {
System.out.println("phone.sendMsg");
}
public synchronized void call() {
System.out.println("phone.call");
}
}
当我们实例化Phone之后,通过对象调用调用其内部的方法时,此时synchronized锁的是这个实例化之后的对象。此时用此对象调用其内部synchronized修饰的方法时都按代码顺序执行
2. 锁当前类
代码如下:
public class Phone {
public static synchronized void iphone8() {
System.out.println("Phone.iphone8");
}
}
当我们调用静态方法iphone8时,此时synchronized锁的是当前的整个类。
3. 锁指定的对象或类
代码如下:
public class Phone {
public void siri() {
Phone phone = new Phone();
synchronized(Iphone.class | phone) {
}
}
}
此时sychronized锁的就是类或对象。
总结
本次内容不多,但是想要理解透还需要大家多练习,多思考。