关于synchronized不能锁定i++的疑问

lazy cat 2016-10-13 05:43:43
在验证i++是不是原子性的过程中,发现用synchronized仍不能使方法同步。请问这是为什么?还有改如何修改才能使结果为0?

代码如下:
public class TestI implements Runnable{
public boolean flag;
public volatile static Integer i = 0;
private int n1 =0;
public void run(){
while(flag==true&&n1<100000){
synchronized(this){
i++;
++n1;
}
}
while(flag==false&&n1<100000){
synchronized(this){
i--;
++n1;
}
}
}
public static void main(String[] args){
TestI t = new TestI();
Thread t1 = new Thread(t);
TestI tt = new TestI();
tt.flag = true;
Thread t2 = new Thread(tt);
t1.start();
t2.start();
try{
t1.join();
t2.join();
}catch(Exception e){};
System.out.println(t.i);
}
...全文
335 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
淡定的蜗牛 2019-01-11
  • 打赏
  • 举报
回复
看这个就够了,拿走拿走,不客气 http://mp.weixin.qq.com/s?__biz=MzU3MDc5NjU2OA==&mid=2247483762&idx=1&sn=d36886881204870e193ea37888226467&chksm=fce8be05cb9f3713aaacae5d91c0651a0ebf604e0a68bb9e06616f90404ec13aece4034bebde#rd
lazy cat 2016-10-13
  • 打赏
  • 举报
回复
楼主自己结贴: 要点如下: 1、不能用this的原因:我用了两个不同的对象创建的线程,所以锁定的是不同的Testi 对象. 2、不能用i的原因:关键在于i++后的i与原来的i竟然不是同一对象,所以第二个线程锁定的i不是第一个线程锁定的i。具体解释可见下面链接:http://blog.csdn.net/luohuacanyue/article/details/8307617
肃穆丶 2016-10-13
  • 打赏
  • 举报
回复
不是啊,,我是说锁定同一个对象,可以使I++ 同步。。不会异步增加
lazy cat 2016-10-13
  • 打赏
  • 举报
回复
引用 8 楼 wangyin970774934 的回复:
[quote=引用 6 楼 yonghuwangwei 的回复:] [quote=引用 5 楼 wangyin970774934 的回复:] 你锁的对象不一样啊,不是同一个对象。 1楼的方法可以吧,,还可以锁当前被加载的类 TestI .class 应该,我没试。。。
恩,是不能锁定this,因为我用的是不同的对象创建的线程,还有就是改成i也不行,i是static变量,应该是同一个对象?[/quote] 对啊。 锁同一个对象 ,可以锁定i++ [/quote] 锁定i++?,不明白
肃穆丶 2016-10-13
  • 打赏
  • 举报
回复
引用 6 楼 yonghuwangwei 的回复:
[quote=引用 5 楼 wangyin970774934 的回复:] 你锁的对象不一样啊,不是同一个对象。 1楼的方法可以吧,,还可以锁当前被加载的类 TestI .class 应该,我没试。。。
恩,是不能锁定this,因为我用的是不同的对象创建的线程,还有就是改成i也不行,i是static变量,应该是同一个对象?[/quote] 对啊。 锁同一个对象 ,可以锁定i++
lazy cat 2016-10-13
  • 打赏
  • 举报
回复
引用 4 楼 bichir 的回复:
如果要用this你可以把TestI tt = new TestI();这个删掉,下面那个线程还是传传t就可以了。 synchronize这里你可能理解有点错误,synchronized(对象xx),是指同一时间只有一个线程能获取到这个对象xx的锁,他后面大括号里只是获取到锁后要干些啥,而不是把大括号里的资源也一起锁定
理解了不能用this的情况,但是static的变量i和字符串的作用应该相同吧,两个线程的i是同一对象,可是改成锁定i也不行?求指点
lazy cat 2016-10-13
  • 打赏
  • 举报
回复
引用 5 楼 wangyin970774934 的回复:
你锁的对象不一样啊,不是同一个对象。 1楼的方法可以吧,,还可以锁当前被加载的类 TestI .class 应该,我没试。。。
恩,是不能锁定this,因为我用的是不同的对象创建的线程,还有就是改成i也不行,i是static变量,应该是同一个对象?
肃穆丶 2016-10-13
  • 打赏
  • 举报
回复
你锁的对象不一样啊,不是同一个对象。 1楼的方法可以吧,,还可以锁当前被加载的类 TestI .class 应该,我没试。。。
bichir 2016-10-13
  • 打赏
  • 举报
回复
如果要用this你可以把TestI tt = new TestI();这个删掉,下面那个线程还是传传t就可以了。 synchronize这里你可能理解有点错误,synchronized(对象xx),是指同一时间只有一个线程能获取到这个对象xx的锁,他后面大括号里只是获取到锁后要干些啥,而不是把大括号里的资源也一起锁定
lazy cat 2016-10-13
  • 打赏
  • 举报
回复
引用 1 楼 bichir 的回复:
synchronized(this)不要用this,在类中声明一个字符串变量然后用那个变量 String final KEY = "KEY"; synchronized(KEY).....
能解释一下为什么用this 或者i 不行吗?我理解是锁定i,然后另一个线程得不到i的锁,需要等待,就不会中断当前线程了。
lazy cat 2016-10-13
  • 打赏
  • 举报
回复
引用 楼主 yonghuwangwei 的回复:
能解释一下为什么用this 或者i 不行吗?我理解是锁定i,然后另一个线程得不到i的锁,需要等待,就不会中断当前线程了。
bichir 2016-10-13
  • 打赏
  • 举报
回复
synchronized(this)不要用this,在类中声明一个字符串变量然后用那个变量 String final KEY = "KEY"; synchronized(KEY).....

62,616

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧