我写了一个计数器类 然后传给三个线程做增长 为什么 synchronizes 字段锁方法时是可以的 锁对象时就不一样了呢。代码如下计数器代码如下
package com;public class Count {
public Count() {
countValue =0;
}
private Integer countValue; public synchronized int getCountValue() {
return countValue;
}
public void setCountValue(int countValue) {
this.countValue = countValue;
}
public Count(int countValue) {
this.countValue = countValue;
}
public  void increaseCount(){
synchronized (countValue) {
int count = countValue;
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
count +=1;
System.out.println(countValue);
countValue = count;
}

}


}
线程调用如下package com;
public class Test {
private static class task implements Runnable{
Count myCount;
int amount;
task(Count count,int amount){
this.myCount = count;
this.amount = amount;
}
public  void run() {
for(int i =1 ;i<=amount;i++){
myCount.increaseCount();
}
}
}

public static void  main(String[] args) throws InterruptedException{
Count c = new Count();
Runnable r = new task(c,10);
        Thread t = new Thread(r);
        Thread t2 = new Thread(r);
        Thread t3 = new Thread(r);
        t.start();
        t2.start();
        t3.start();
        t.join();t2.join();t3.join();
        System.out.println(c.getCountValue());
      }
}如果红色部分写成 public synchronized void increaseCount(){

则打印 0到30  也就是我想要的同步效果但是如果按照上面的那样 锁了这个countValue对象 却打印了 
0
1
1
2
2
3
3
4
5
5
5
6
6
7
7
8
8
9
9
10
10
11
11
12
12
13
14
14
14
15
16
为什么呢?

解决方案 »

  1.   

    你锁的对象不对,应该是synchronized (this)  这样的话也是你想要的结果。而不是锁住你的变量。
      

  2.   

    increaseCount()定义System.out.println(countValue);
    重复了
    这个打印结果是全地吗
      

  3.   

    锁方法时 是this锁,你那个countValue 实例变量,所以锁不住,把他改成
    private static Integer countValue就以,因为是类变量,实例共享
      

  4.   


    我知道this这个写法 但是为什么锁变量锁不住呢 (因为项目中有个方法这样用的 锁的变量)
      

  5.   

    本帖最后由 kokobox 于 2010-04-01 11:46:41 编辑
      

  6.   

    java.util.concurrent.locks 接口控制细节.....
      

  7.   

     Integer i = 199;
           if(i==(++i))
            System.out.println("equals");
           else
            System.out.println("not equals"); 
          }i自加以后,就变成另一个对象了,所以那个锁没用的。
      

  8.   

    上面那个例子不对,i会自动装箱成int,就比较值了,
    举不出例子,不过Integer和String 一样吧,改变了就产生一个新对象。具体这个新对象怎么测试。我一下子想不出来
      

  9.   

    通过看Integer源码,我理解了,Integer 每变一次就会有产生一个新对象
    new Integer(i);