加到方法上面
以同步块的形式使用
最大的作用是确保多个线程在同一时刻,只能有一个线程处于方法和同步块之中.
这样保证了线程对变量访问的
可见性和排他性synchronized关键字,是由java语言本身为我们提供的,所以说我们习惯性把synchronized关键字称为内置锁.
synchronized锁的其实是一个具体的对象
每个对象在内存中会被编译成class文件,内存的对象头上有一个标志位, 标志位上有1~2个字节的锁
使用synchronized关键字,就是线程去抢那个标志位,谁把标志位指向了自己,谁就抢到了锁,这又产生了对象锁,类锁的概念.
方法直接用synchronuzed关键字修饰的时候
在方法体里面:
synchronized(this) {
}
的时候.
两个线程同时锁相同的对象,先获得锁那个线程先运行完毕另一个线程才开始运行
两个线程锁不同的对象,意味着两个线程是可以同时进行的.
static,并使用了synchronized关键字注:
- 用Spring框架的时候,Spring框架没有做特殊设置的话,Spring为我们new出的对象实例有且只有一个,这时候用synchronized可以保证锁定是唯一的一个对象.
- 如果配置了Spring允许new出多个对象,这时候再来加锁的时候千万要注意synchronized关键字锁的会不会是同一个对象.
volatile关键字是由虚拟机为我们提供的一个最轻量级的同步机制
某个变量加上volatile关键字后,其实是告诉虚拟机每次要用变量的时候从主内存中读取,
volatile在使用的时候,不会对读取写入加锁,所以是最轻量的同步机制,效率也是最高的
volatile不是线程安全的,只能保证某个变量的可见性,不能保证变量的原子性
比如:
如果是:
public void setAge(){ age = age + 20; }的话,虚拟机并不能保证操作是原子性的.
只有一个线程写,多个线程读是volatile最常使用的场景
jdk源码里,使用volatile关键字的地方相当多
线程变量
可以确保每个线程他只使用自己那部分的
在线程里定义一个变量,只要以ThreadLocal包装,可以确保每个线程只会使用自己的一份拷贝
链接池里面会使用ThreadLocal,每一个线程拥有自己独有的链接.
Spring事务处理也有用到ThreadLocal