https://www.cnblogs.com/xyabk/p/10901291.html
synchronized
的用法可以这么理解
在执行到被synchronized
划定范围的代码时,会去查看一个标识
①如果这个标识没有被上锁,将这个标识锁上,待执行完毕后解锁
②如果这个标识被上锁了,则等待解锁
synchronized 的三种应用方式(以什么作为了标识)
实际上,每个对象都有一个内部锁,使用 synchronized 关键字使用的就是这个内部锁。
1.修饰代码块
//括号内的参数应该是一个具体对象
synchronized(Object object){
}
例:
class Timer{
private static int num=0;
public void funSyn1() {
int i;
xxxxx;
synchronized (this) {
//synchronized (object) {
num++;
}
xxxxx;
xxxxx;
}
public void funSyn2() {
int i;
xxxxx;
synchronized (this) {
//synchronized (object) {
num++;
}
xxxxx;
xxxxx;
}
public void funSyn3() {
int i;
xxxxx;
num++;
xxxxx;
xxxxx;
}
}
在执行 synchronized 包围的代码块时,会检查 括号内的 参数对象是否被上锁(也就是将括号内的对象作为标识)
如果括号内是 this
关键字,则检查 调用此方法的类的实例 是否被上锁(也就是将调用该方法的这个此类的实例作为标识)
Timer t1,t2;
不同线程执行 t1.funSyn1 与 t1.funSyn1 与 t1.funSyn2 中synchronized修饰块内代码的时候,会同步(因为它们执行的时候都会先去 检查 t1 有没有锁住)
不同线程执行 t1.funSyn1 与 t2.funSyn1 与 t1.funSyn3 中synchronized修饰块内代码的时候,不会用不(它们执行的时候分别是 检查 t1 与 检查 t2 与 不检查直接执行)
2.修饰类的方法
Class A{
public synchronized void fun(){
xxx;
xxx;
}
}
等效
Class A{
public void fun(){
synchronized(this){
xxx;
xxx;
}
}
}
在修饰类的方法时,相当于将this
作为参数,将整个方法作为代码块,与 上种情况类似
- 修饰静态方法
Class T{
public synchronized static funSyn1(){
}
public synchronized funSyn2(){
}
}
修饰静态方法时,调用该静态方法时,会先检查该类是否上锁(可以理解为 将 类T 作为 标识)(实际上是对 T.class 这个对象的内部锁上锁)
T t1;
不同线程执行 T.funSyn1 与 T.funSyn1 与 t1.funSyn1 时,会同步(因为执行的时候会先检查 类T 与 类T 与 类T 是否上锁)
不同线程执行 t1.funSyn1 与 t1.funSyn2 时,不会同步(因为执行的时候会先检查类T 与 实例 t1 是否上锁)
网友评论