您的位置:首页 > 其它

对synchronized的理解

2016-03-21 14:57 295 查看
其实如果不懂,自己写一个例子出来跑一跑,就什么都知道了。

synchronized一共两种用法:

1、放在方法前面声明方法

2、synchronized(xxx){ //TODO} 形成代码块

第一种放在方法前面声明方法时,即:

public synchronized void func(){
//TODO
}
假设此方法分别被Thread_1和Thread_2两条线程无限循环地调用,那么此时的调用顺序为:



可以看到,当方法被线程1调用完,就会立刻被线程2调用;线程2调用完毕,又会立刻被线程1调用,该方法是不会同时调用的。

第二种代码块的方法,用于作为线程锁的东西有很多,分别有:

1、普通对象

public Object mLock = new Object();

public void func(){
synchronized(mLock){
//TODO
}
}


这种写法是针对同一个对象中,多条线程的同步问题的。

假如我在一个对象中,有多个内部方法都用到了这个锁,然后分别被多个线程所调用,那么线程间会根据这个mLock成员的监控情况进行线程同步。

比如,当前有func1()、func2()、func3()、func4()四个方法都用到这个代码块线程锁,而有Thread_1、Thread_2、Thread_3、Thread_4条线程分别调用这四个方法并同时开启线程。虽然线程是同步开启,但是从哪个线程开始先执行是不确定的,我们假设线程1先被执行,此时mLock被fun1中的代码块所监控着,线程2、3、4都必须等待这个mLock被释放了,才可以继续运行,否则将一直等待,直到线程1中的fun1被执行完成,然后mLock被释放为止。

2、静态对象

public static Object mLock = new Object();
调用方法和上述1中的方式一样,不同之处在于代码块中的线程锁对象为静态对象。

静态对象是针对同一个类的多个对象中,每个对象之间的线程同步问题的。

举个例子,在一个类中,有一个静态变量:

public static int index = 0;


此时我们生成了3个这个类的对象,每个实例都可以调用线程改变这个index,比如为其递增1(index++)。并且加到index = 20时就退出不再改变。

如果不进行线程同步,就会发生index被同时index++,此时index将出现超过20的情况。所以就要用到这个静态对象的锁,保证多个对象之间各自的线程能保持同步。

3、synchronized(this)

这里的用法和上述1中的意思和作用一样,不同的是,1中用的锁的成员为自己定义的Object,而这里的锁的成员为当前类的实例。

比如,当前有一个类Class_1,这个类中的方法用了这个synchronized(this)。而这个类所生成了两个对象class_object_1和class_object_2。那么对于这两个对象而言,他们的synchronized(this)中的this就是指其对象本身,即class_object_1这个对象的中的synchronized(this)中的this指的是class_object_1。

4、synchronized(Class.this)

这里的用法和上述2中的意思和作用一样。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: