借用一个程序 来说明 多线程 和单态 以及 对象在两种情况下的存储方式。

2009-12-16


public class TestMain {
    public static void main(String args[]){
        TestSynchronized r1 = new TestSynchronized();
        TestSynchronized r2 = new TestSynchronized();
        Thread t1 = new Thread(r1, "t1");
        Thread t2 = new Thread(r1, "t2");
        t1.start();
        t2.start();
       
    }
     
}
class TestSynchronized implements Runnable
{
    private int j = 0;
    public void run()
        {
        for(int i=0; i<3; i++)
        {

            Single.getInstance().printsth();
        }
    }
}

class Single{
    private static Single instance;
    private A a;
    private Single() {
        this.a  = new A();
        System.out.println("Called new Instance A Constructor Mathod");
       
    }
    public static Single getInstance(){
        if(instance==null){
            instance = new Single();
            System.out.println("Called new Instance Single Constructor Mathod");
        }
        /*instance = new Single();
        System.out.println("Called new Instance Single Constructor Mathod");*/
            return instance;
       
       
    }
    public synchronized  void   printsth(){ //  假如不加synchronized 关键字的话。出来的i 值 将毫无规律。
       
        int i = a.getI();
       
        i++;
        a.setI(i);
        System.out.println(Thread.currentThread().getName()+": A reference is  "+a.toString()+"and A.is is"+a.getI());
    }
   
}
class A{
    private int i;

    public int getI() {
        return i;
    }

    public void setI(int i) {
        this.i = i;
    }
   
}

-------------------

下面的结果是用了同步关键字

Called new Instance A Constructor Mathod
Called new Instance Single Constructor Mathod
t2: A reference is  test.A@10b30a7and A.is is1
t2: A reference is  test.A@10b30a7and A.is is2
Called new Instance A Constructor Mathod
Called new Instance Single Constructor Mathod
t1: A reference is  test.A@1a758cband A.is is1
t1: A reference is  test.A@1a758cband A.is is2
t1: A reference is  test.A@1a758cband A.is is3
t2: A reference is  test.A@10b30a7and A.is is3

 

-------

下面的结果是没有用同步关键字

“t1: A is A@d9f9c3 and A.i is 1
t2: A is A@d9f9c3 and A.i is 2
t1: A is A@d9f9c3 and A.i is 3
t2: A is A@d9f9c3 and A.i is 4
t1: A is A@d9f9c3 and A.i is 5
t2: A is A@d9f9c3 and A.i is 6”

 

每个Single 对象下面都有一个A 实例, 多线程t1 和 t2 到底访问那个单态下面的A实例,不一定的。

 

------

 

t2 Called new Instance A Constructor Mathod and A is A@d9f9c3
t1 Called new Instance A Constructor Mathod and A is A@757aef
t2 Called new Instance Single Constructor Mathod and Single is Single@9cab16
t1 Called new Instance Single Constructor Mathod and Single is Single@1a46e30
t2: A reference is  A@757aefand A.is is1
t1: A reference is  A@757aefand A.is is2
t2: A reference is  A@757aefand A.is is3
t1: A reference is  A@757aefand A.is is4
t2: A reference is  A@757aefand A.is is5
t1: A reference is  A@757aefand A.is is6

 

从上面的程序可以看出来, A@d9f9c3 是在Single@9cab16 下面的, 而 A@757aef 是Single@1a46e30 下面的。

但是t2 和t1 缺选择了一个A@757aef 这个对象。可以想象成这样,两个CPU (t1 和t2),内存里两个A对象的实例,两片内存块。

这两个cpu 到底选择哪个内存块 不一定的。随机的。 但是要向把A对象里的I 值 线性的顺序的输出的话,则需要加上同步关键字。

 

 

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值