EP34-线程同步(Synchronized)

插曲是一件小事

最近有人批评了DrunkPianoDaily这一系列的日报。大概意思是我不懂装懂。说者无心,我听了还蛮难过的。

后来换他人角度想了一下,天天发邮件其实蛮惹人厌的。所以明天起我每天把日报的内容直接发布在我的上啦,欢迎检查;不再发邮件了。


Thread的同步与锁

今天学习了同步与锁。同步就是线程同步(synchronized),锁是同步的实现手段;

线程的同步是为了防止多个线程访问一个数据对象时,对数据造成的破坏。

比如两个线程同时操作一个对象,修改里面变量的值,每个线程都隔一秒把某个变量x的数值减少10,那么打印出来会发生抢占的现象,一个线程操作完了x,另一个线程接着操作了它,就一下子减少了20。

解决的办法是保证同一时刻只有一个线程在修改x的值。
给修改x值的那个函数加上synchronize关键字,或者用同步代码块包裹修改x值的代码。

下面的代码,一些线程执行其中的one方法,一些线程执行two方法,如果不加synchronized,打印出来的可能是i = 3,j = 4这种情况。原因就是two方法可能先读到了没有+1的i,又读到了+1的j。

class Test {  
    static int i = 0, j = 0;  
    static synchronized void one() {  
        i++;  
        j++;  
    }  
    static synchronized void two() {  
        System.out.println("i=" + i + " j=" + j);  
    }  
} 

至于为什么会产生i++,j++不同时执行、打印出来不一样大的情况,我想了一下,我猜大概是这样:

  • 第一种情形:
    i,j会被分批读进内存->改变值->刷新内存,这样就可能产生第一个线程里i刚加完,j还没开始加,第二个线程里又开始执行i++,j++了,这样i就比j大了所以加个锁的话,第二个线程就会阻塞住,等第一个线程里的i++,j++都执行完了才执行,就不会出现i跟j不一样大的情况了。

  • 第二种情形
    因为``` System.out.println("i=" + i + " j=" + j);


-


Reference:
[1]http://blog.csdn.net/ghsau/article/details/7424694
[2]http://www.cnblogs.com/linjiqin/p/3208843.html

你可能感兴趣的:(EP34-线程同步(Synchronized))