Java对象奇异现象,求解

[code="java"]
public static void main(String[] args) {
Integer count = new Integer(0);
new SendThread(count).start();
new SendThread(count).start();
new SendThread(count).start();
new SendThread(count).start();
new SendThread(count).start();
}
[/code]

[code="java"]
public class SendThread extends Thread {
public Integer count = 0;
public SendThread(Integer count) {
this.count = count;
}

@Override
public void run() {
    while (true) {
            synchronized(count){
                    count++;
                    System.out.println(getName()+ ",number:"+count);
            }

            try {
                Thread.sleep(10);
            }
            catch (InterruptedException e) {
                e.printStackTrace();
            }
      }
}

}
[/code]
运行结果如下:

Thread-1,number:1
Thread-3,number:1
Thread-0,number:1
Thread-2,number:1
Thread-4,number:1
Thread-0,number:2
Thread-1,number:2
Thread-2,number:2
Thread-3,number:2
Thread-4,number:2
Thread-0,number:3
Thread-4,number:3
Thread-2,number:3
Thread-3,number:3
Thread-1,number:3


Integer不是对象吗?那这5个线程,不是都是同一个对象上进行累加吗?为什么每个线程打印出来的值都是从1开始呢?

这到底是为什么呢为什么呢?

为了说明问题,稍微改了一下代码
[code="java"]

public class IntegerTest {
static Integer count = new Integer(0);

public static void main(String[] args) {

    new SendThread(count).start();
    new SendThread(count).start();
    new SendThread(count).start();
}

static class SendThread extends Thread {
    public Integer count1;

    public SendThread(Integer count) {
        //count1指向count
        this.count1 = count;
    }

    @Override
    public void run() {
        for (int i = 0; i < 10; i++) {
            synchronized (count1) {
                //count1自加,新的对象,count不变(不可变对象)
                count1++;
                if (count1 == count)
                    System.out.println("你在做梦");
                System.out.println(getName() + ",number:" + count1);
            }

            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

}
[/code]

对比String\BigDecimal\BigInteger之类,都是Immutable

[code="java"]synchronized(count){

count++;

System.out.println(getName()+ ",number:"+count);

} [/code]
count++这里涉及了自动拆箱,自动拆箱的话值是存放在堆中的。
public Integer count = 0; 定义的成员变量count就拆箱一次放到栈中,那么当再次装箱之后是否还将拆箱的count装到原来的count引用指向的堆中的对象呢?
我没有很深入地研究过JVM,这个就不清楚了。
按照运行的效果来看的吧,他们已经不指向同一个地址了,希望你确认了之后能分享一下这个例子的终极理论。

Integer是对象 但此处的Integer并非静态的所以它们每个线程创建时用的肯定不是同一个.

这是因为Integer从来就没创建过对象
new Integer(0)这句话没创建任何对象

三楼也太扯淡了吧,不晓得你从哪里看来的。
事实证明是创建了对象的,你若不信你可以用int定义的变量和new Integer(0)创建出来的对象对比一下,具体怎么对比,debug。

Integer 是不可变对象,这才是关键

由此可见,我的回答是对的,就是因为在count++的时候执行了自动拆箱和装箱。
但是装箱的时候count对象已经不是原来的count对象了,引用已改变。
OK可以结束这个迷惑了。

public final class Integerextends Numberimplements Comparable

哎chen_yongkai说的有道理,其实不可变所有拆箱后装箱就改变了也不是错的吧,呵呵。
因为肯定拆箱并装箱了。

Integer 的hashCode 就等于他的值,多看看jdk源码

integer的hashCode重写过,就是它本身的int值,这是为了方便判断两个integer的是否相等。
就好比我们自己实现的domainModel一样,常常需要去重写hashCode和eqauls方法。
public int hashCode() {
return value;
}
这是Integer的hashCode方法源码。
如果你说Integer的class的hashCode一样的话,那就更不用说了,因为相同类的字节码jvm只加载一份。

不同的对象可以有相同的hashCode,所以不能用hashCode比较对象是否一样,要用==号比较

Integer a=new Integer(1);
Integer b=new Integer(1);
这两个的hashCode相等,但不是相同的对象

如果Integer是不可变对象那么如下是不是会输出0呢?
Integer a = 0;
System.out.println(++a);

你的理解混乱了
Integer a = 0;
Integer b=a;
System.out.println(++a);
System.out.println(b);

b 打印出来是0,这里反映的是不可变对象的性质

++a已经不是原来的对象了

你试试把a==b的结果打印出来呢?

当然是false了,我一开始贴的代码就说明了,都不用试
打出来的值一个是0 一个是1,能相等吗?
我好晕!

看来楼主很难理解final的意思,终极不可变啊。

++a,如果是int的话,原本的执行如下:
1、找到a的地址
2、将a自增1
3、返回自增之后的a

第三点不理解没关系,按照如上理解,那么a的地址不会变,有没有问题?

但是现在它是integer

chen_yongkai同学写的:

Integer a = 0;
Integer b=a;
System.out.println(++a);
System.out.println(b);

执行之后a的地址被改变了,b还指向原来a的地址
所以用==比较a和b返回false

其实这里执行的时候
就是拆箱之后再装箱的时候,重新new了一个,跟字符串连接是一个道理。

我认为原因是jvm中每创建一个线程就会分配一个java栈。count对象在每个java栈中都有一份,所以每个线程都会从0开始