JAVA同步块,让我纠结了好久 java同步 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 要理解这个问题,就要明白synchronized的原理,当你给synchronized传一个对象obj时,作用就是,会让访问synchronized同步块的线程竞争obj对象的锁,注意这里的意思,意思是,我抢到了obj对象的锁,我就能访问obj对象里的同步块,而别的线程用同一个obj对象来访问就不能同时访问。所以,结合你的代码来说,synchronized(this)的效果就是,我抢到了 Sync 对象的锁,我可以访问那个 Sync 对象中的synchronized同步块,而别的线程因为也是通过 同一个Sync 对象(都是this)来访问同步块的,所以不能访问,就是说排斥相同的对象。而synchronized(i)的效果是,我抢到了Integer对象的锁,但是我访问同步块的时候,我是 Sync 对象,不是Integer对象 ,所以你锁住Integer对象没有用,它不会排斥Sync 对象,因此就不同步了。 总结一下,就是,你是要锁住 Sync 对象,因为你的同步块是 Sync 对象里面的。 谢谢你的回答。但是我还是有疑问。如果我在Sync类里面定义一个private Object obj = new Object();然后,同步块锁住obj,结果也是对的。synchronized(obj)按照你说的,也不会排斥Sync对象,那这个怎么解释呢? 可以参考http://blog.csdn.net/skywalker_only/article/details/38927919 可以创建连个Object对象obj1和obj2,分别synchronized(obj1)和synchronized(obj2),看看效果 Integer这个对象用作运算时,会自动拆箱与装箱。例:[align=center]Integer i = new Integer(0);i = i+1这里要分解成下面1、Integer i = new Integer(0);2、int tmp = 0;3、tmp = tmp +1;4、i = new Integer(tmp);[/align]看第4步,这里i指向的对象已经变了,所以你锁住的i不是同一个对象,当然锁不住了。 我可以这么理解吗?synchronized锁住的是对象的引用呗?如果引用不改变,那么就能锁住对象。我上面是因为对象的引用改变了,所以锁不住。如果我声明的是List,那么我在List里面添加元素,只要不改变引用就能锁住对象。 你锁不住的原因是在线程中使用了for循环,方法执行完了就释放锁了,其它线程就可以获取同一个对象的锁了,可以去掉for循环再试试。 public void run() { synchronized (i){ for (int j = 0; j < 100000; j++) { increment(); } System.out.println(i); }}在你的for前加对象锁,你for循环内的方法里面加锁,没执行一次循环锁就释放了,没有效果 我可以这么理解吗?synchronized锁住的是对象的引用呗?如果引用不改变,那么就能锁住对象。我上面是因为对象的引用改变了,所以锁不住。如果我声明的是List,那么我在List里面添加元素,只要不改变引用就能锁住对象。是这样的,锁是不管对象里面的内容怎样改变 Integer是不可变类,它代表的值是不能变的,所以当你调用i = i + 1;后,实际上变量i引用的对象已经变化了,而你锁住的是原来的i所引用的对象,其它线程在进入同步块时要锁的对象是新的对象,而新的对象是没被加锁的 非常赞同 @wu244534279的答案,需要注意两点1.每一个对象对会有对象锁,同步资源时,需要用同一个对象锁。2.对于Integer类型 运算时,会出现拆箱和装箱。 jtree与jtextpane的同步 泛型类的嵌套 新年,菜鸟继续努力,一定要学好JAVA 求一个高性能的读取文本文档方法 急!!!关于BIRT和MYSQL之间的中文问题!!!有用MYSQL做过BIRT的朋友指点啊!! 重写equals方法新问题 加密算法之md4算法js源程序 新手问题,急,在线等 把JComboBox在JTable里的严重问题! 请教关于NetBean 7的JUnit插件问题,谢谢! 关于线程等待问题 使用java语言启动打印机
总结一下,就是,你是要锁住 Sync 对象,因为你的同步块是 Sync 对象里面的。
但是我还是有疑问。如果我在Sync类里面定义一个
private Object obj = new Object();
然后,同步块锁住obj,结果也是对的。
synchronized(obj)
按照你说的,也不会排斥Sync对象,那这个怎么解释呢?
例:
[align=center]Integer i = new Integer(0);
i = i+1
这里要分解成下面
1、Integer i = new Integer(0);
2、int tmp = 0;
3、tmp = tmp +1;
4、i = new Integer(tmp);[/align]
看第4步,这里i指向的对象已经变了,所以你锁住的i不是同一个对象,当然锁不住了。
我可以这么理解吗?synchronized锁住的是对象的引用呗?如果引用不改变,那么就能锁住对象。
我上面是因为对象的引用改变了,所以锁不住。
如果我声明的是List,那么我在List里面添加元素,只要不改变引用就能锁住对象。
synchronized (i){
for (int j = 0; j < 100000; j++) {
increment();
}
System.out.println(i);
}
}在你的for前加对象锁,你for循环内的方法里面加锁,没执行一次循环锁就释放了,没有效果
我可以这么理解吗?synchronized锁住的是对象的引用呗?如果引用不改变,那么就能锁住对象。
我上面是因为对象的引用改变了,所以锁不住。
如果我声明的是List,那么我在List里面添加元素,只要不改变引用就能锁住对象。
是这样的,锁是不管对象里面的内容怎样改变
需要注意两点
1.每一个对象对会有对象锁,同步资源时,需要用同一个对象锁。
2.对于Integer类型 运算时,会出现拆箱和装箱。