synchronized关键字用法简述

来源:互联网 发布:协作办公平台 知乎 编辑:程序博客网 时间:2024/04/29 07:14

synchronized的同步简单来分的话可以分为两个层次:

1. 对象级别的同步控制

    对象级别的同步,顾名思义,这样的同步是针对某一个对象的同步; 类中的非static方法如果冠以synchronized修饰符或者方法中的synchronized(对象)块都是这样的运用。  

例如:

Class A{

    byte[] bt = new byte[0];

    public A(){}

 

    public synchronized void methodA(){....}

    public void methodB(){

      synchronized(bt ){....}

     }

    }

 

...

A objA = new A();

A objB = new B();

.....

 

1号线程正在执行对象objA的methodA方法,在其未执行完成之前如果2号线程期望调用objA.methodA(),那么2号线程将处于等待状态;直到1号线程执行完objA.methodA()并释放objA对象锁之后如果2号线程成功获取到objA的对象锁那么2号线程才可以进入ojbA.methodA()方法并执行其代码。但是同时其他线程可以调用objB.methodA(),而不会因为1号线程调用objA.methodA()而受影响;因为每一个对象都有一个对象锁,虽然1号线程获取了ojbA的对象锁,但是ojbB得锁并不受到影响。

 

...

synchronized(bt ){....}

 

...

这个同步块使用的对象bt的锁,其被调用的情况和methodA()一样。只不过这里是判断线程是否获取到bt的对象锁,而不是判断是否获取到objA或者ojbB的对象锁。

 

在这里objA.methodA()和objA.methodB()中的 synchronized(bt ){....}的同步块可以并发执行,因为他们需要的锁不同,objA.methodA()需要的是objA的对象锁,而objA.methodB()中的 synchronized(bt ){....}需要的是bt的对象锁。

 

 

2. 类级别的同步控制

这样的同步机制是对一个类及其所有对象是生效的。

例如:

class C{}

class B{

public static synchronized void methodD(){}

public void methodE(){

synchronized(C.class){...}

}

 

}

 

...

B objC = new B();

B objD = new B();

...

 

1号线程在调用objC.methodD(),此时2号线程期望调用objD.methodD();在1号线程执行objC.methodD()未完成时,2号线程可以进入objD.methodD()中执行代码吗? 不可以! 注意methodD()方法前面有static修饰符,这以为着该方法的同步是类一级别的;在调用这样的同步方法时会检查线程是否持有相应类的锁,而不是检查是否持有对象的锁!

 

同步块synchronized(C.class){...}使用的是类C的锁,执行到该块时会检测当前线程是否持有类C的锁,若持有则进入该块。

 

 

 

注:同步机制多用于临界资源处理、多线程等场合。

 

 

 

 

错误和不完善的地方敬请指正,欢迎交流。