0
点赞
收藏
分享

微信扫一扫

synchronized修饰变量


关于synchronized的初步使用,大家看拙作

​​关于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的缓存的


举报

相关推荐

0 条评论