关于synchronized的初步使用,大家看拙作
即可
不过今天,有个朋友问我,如果用synchronized修饰一个类的成员变量会怎么样?
咱们看下面的代码
package thread;
public class ThreadTestffd {
private Integer a = 0;
private Integer b = 0;
public static void main(String[] args) {
ThreadTestffd test = new ThreadTestffd();
test.A();
test.B();
}
public void A() {
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("A线程准备");
synchronized (a) {
System.out.println("A线程开始");
for (int i = 0; i < 10; i++) {
System.out.println("a" + i);
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}).start();
}
public void B() {
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("B线程准备");
synchronized (b) {
System.out.println("B线程开始");
for (int i = 0; i < 10; i++) {
System.out.println("b" + i);
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}).start();
}
}
最后的结果是先等a方法运行完之后,才打印出来b线程开始,当然"b线程准备"很早就打印了
这说明什么,我猜测就是:
用synchronized修饰成员变量,就直接限制了这个对象实例,synchronized(成员变量)就等于synchronized(this)
那如果有两个对象呢?
就像我把代码改成:
private Integer a = 0;
private Integer b = 0;
public static void main(String[] args) {
ThreadTestffd test = new ThreadTestffd();
test.A();
ThreadTestffd test2 = new ThreadTestffd();
test2.B();
}
那结果应该是什么样的?
应该是交错打印的么?
应该是的,毕竟两个对象么
但是结果不是,结果是先打印a然后打印b
卧槽?日了狗了!
我脑子忽然想到一个问题,要不咱换一个成员变量?
private Person a=new Person();
private Person b=new Person();
public static void main(String[] args) {
ThreadTestffd test = new ThreadTestffd();
test.A();
test.B();
}
最后的结果是交替打印,Person就是一个简单的pojo类
我靠什么情况?integer和pseron的结果不一样
后来,我忽然想到了integer是有缓存的,如下:
public static Integer valueOf(int i) {
assert IntegerCache.high >= 127;
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
在-128到127直接的都是一个对象
也就是说最开始的代码,虽然一个锁a一个锁b,但是锁的都是同一个对象
后面的,把ab改成了person,就交替打印了,因为a和b压根就不是同一个对象
所以上面的结论:
用synchronized修饰成员变量,就直接限制了这个对象实例,synchronized(成员变量)就等于synchronized(this)
也是不对的
synchronized(成员变量A)与synchronized(成员变量B)是没有关系的,他们互补干扰
其实也对,既然用锁,那就一个对象么,一个a一个b什么鬼?
伙计说:我就测试测试....
其实这篇博客的名字应该叫谈谈integer的缓存的