解决方案 »

  1.   

            要理解这个问题,就要明白synchronized的原理,当你给synchronized传一个对象obj时,作用就是,会让访问synchronized同步块的线程竞争obj对象的锁,注意这里的意思,意思是,我抢到了obj对象的锁,我就能访问obj对象里的同步块,而别的线程用同一个obj对象来访问就不能同时访问。所以,结合你的代码来说,synchronized(this)的效果就是,我抢到了 Sync 对象的锁,我可以访问那个 Sync 对象中的synchronized同步块,而别的线程因为也是通过 同一个Sync 对象(都是this)来访问同步块的,所以不能访问,就是说排斥相同的对象。而synchronized(i)的效果是,我抢到了Integer对象的锁,但是我访问同步块的时候,我是 Sync 对象,不是Integer对象 ,所以你锁住Integer对象没有用,它不会排斥Sync 对象,因此就不同步了。
            总结一下,就是,你是要锁住 Sync 对象,因为你的同步块是 Sync 对象里面的。
      

  2.   

    谢谢你的回答。
    但是我还是有疑问。如果我在Sync类里面定义一个
    private Object obj = new Object();
    然后,同步块锁住obj,结果也是对的。
    synchronized(obj)
    按照你说的,也不会排斥Sync对象,那这个怎么解释呢?
      

  3.   

    可以参考http://blog.csdn.net/skywalker_only/article/details/38927919
      

  4.   

    可以创建连个Object对象obj1和obj2,分别synchronized(obj1)和synchronized(obj2),看看效果
      

  5.   

    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不是同一个对象,当然锁不住了。
      

  6.   


    我可以这么理解吗?synchronized锁住的是对象的引用呗?如果引用不改变,那么就能锁住对象。
    我上面是因为对象的引用改变了,所以锁不住。
    如果我声明的是List,那么我在List里面添加元素,只要不改变引用就能锁住对象。
      

  7.   

    你锁不住的原因是在线程中使用了for循环,方法执行完了就释放锁了,其它线程就可以获取同一个对象的锁了,可以去掉for循环再试试。
      

  8.   

    public void run() {           
    synchronized (i){
                for (int j = 0; j < 100000; j++) {
                    increment();
                }
                System.out.println(i);
            }
    }在你的for前加对象锁,你for循环内的方法里面加锁,没执行一次循环锁就释放了,没有效果
      

  9.   


    我可以这么理解吗?synchronized锁住的是对象的引用呗?如果引用不改变,那么就能锁住对象。
    我上面是因为对象的引用改变了,所以锁不住。
    如果我声明的是List,那么我在List里面添加元素,只要不改变引用就能锁住对象。
    是这样的,锁是不管对象里面的内容怎样改变
      

  10.   

    Integer是不可变类,它代表的值是不能变的,所以当你调用i = i + 1;后,实际上变量i引用的对象已经变化了,而你锁住的是原来的i所引用的对象,其它线程在进入同步块时要锁的对象是新的对象,而新的对象是没被加锁的
      

  11.   

    非常赞同 @wu244534279的答案,
    需要注意两点
    1.每一个对象对会有对象锁,同步资源时,需要用同一个对象锁。
    2.对于Integer类型 运算时,会出现拆箱和装箱。