synchronized关键字

1.synchronized关键字的作用和用法

使用synchronized修饰的方法或则代码块,具有同步的特性,即同一时间最多只有一个线程能执行这段代码,实现了多线程的同步执行。

用法

a)       用于普通方法

示例:

public synchronized void sayHello(String str){

System.out.println(“hello~”+str);

}

这种用法是对当前对象加锁,最多一个线程能执行当前对象的synchoronized方法。

b)       用于静态方法

public static synchronized void sayHello(String str){

System.out.println(“hello~”+str);

}

对类方法所属的类的class对象加锁,最多一个线程能执行当前类的synchronized静态方法。

c)        用于代码块

public void sayHello(String str){

synchronized(object|class){

System.out.println(“hello~”+str);

}

}

可对普通实例对象加锁也可以对class对象加锁。

2.synchronized原理

每一个对象都有一个monitor内置对象,线程要执行被synchronized修饰的方法或代码块,必须要获得monitor的所有权。

一个同步方法会被编译器编译成如下的样子:

源码:

public class SynchronizedDemo {

     public void method() {

         synchronized (this) {

             System.out.println("Method 1 start");

         }

     }

}

反编译.class字节码文件

 

如图,一个同步方法代码在执行前会先执行请求对对象的monitor加锁的指令,在代码执行结束后再释放对monitor的锁以便其他线程对monitor加锁。

具体流程是这样:

1).一个线程在执行一个同步方法时,如果该线程还没有对monitor加锁,会先去看对象的monitor进入数是否为0——如果为0:请求对monitor加锁,然后monitor的进入数会加一;如果不为0:线程会进入阻塞状态知道monitor的进入数变成0(以及获得资源比如时间片)再去对monitor请求加锁。

若果该线程已经对monitor加锁,monitor的进入数会加一。

2).当代码执行结束后, monitor的进入数会减一,如果monitor恰好变为0,会释放monitor。

原文地址:https://www.cnblogs.com/zhihow/p/9826179.html