Guimashisqll 2015-07-30 20:11 采纳率: 50%
浏览 1708
已采纳

Java 多线程问题 synchronized(obj)的疑惑

是这样的,我想知道synchronized(obj)的用法,然后写了如下的代码,运行结果我如何都搞不清,还请各位指点。

代码1:

 public class MyObj 
{
    private Integer a;
    private Double b;
    private Integer c;

    public void setA()
    {
        System.out.println(Thread.currentThread().getName() + "抢到锁..setA");
        synchronized(c)
        {
            System.out.println("    " + Thread.currentThread().getName() + " " + this.a + "  " + this.b);
            this.a = 1;
            this.b = 2.0;
            try{
                Thread.sleep(200);//(int) (Math.random()*2000)
            }catch(InterruptedException e)          {
                e.printStackTrace();
            }
            System.out.println("   " + Thread.currentThread().getName() + " " + this.a + "  " + this.b);
        }
    }
    public void setB()
    {
        System.out.println(Thread.currentThread().getName() + "抢到锁....setB");
        synchronized(c)
        {
            System.out.println("    " + Thread.currentThread().getName() + " " + this.a + "  " + this.b);
            this.a = 3;
            this.b = 4.0;
            try{
                Thread.sleep(200);//(int) (Math.random()*2000)
            }catch(InterruptedException e)          {
                e.printStackTrace();
            }
            System.out.println("    " + Thread.currentThread().getName() + " " + this.a + " " + this.b);
        }
    }
    public MyObj()
    {
        this.a = -1;
        this.b = -1.0;
        this.c = 0;
    }
}

代码2:

 public class Change 
{
    private MyObj myObj;

    public Change(MyObj myObj)
    {
        this.myObj = myObj;
    }

    public static void main(String args[])
    {
        final MyObj myObj = new MyObj();
        final Integer a = 1;

        Thread thread1 = new Thread(new Runnable(){
            public void run()
            {
                for(int product = 1; product <= 3; ++product)
                {
                    try{
                        Thread.sleep((int) (Math.random()*200));//(int) (Math.random()*2000)
                        myObj.setA();
                    }catch(InterruptedException e)
                    {
                        e.printStackTrace();
                    }

                }
            }
        },"thread1");

        Thread thread2 = new Thread(new Runnable(){
            public void run()
            {
                for(int product = 1; product <= 3; ++product)
                {
                    try{
                        Thread.sleep((int) (Math.random()*200));//(int) (Math.random()*2000)
                        myObj.setB();
                    }catch(InterruptedException e)
                    {
                        e.printStackTrace();
                    }
                }
            }
        },"thread2");

        thread1.start();
        thread2.start();

    }
}

输出结果(之一):
thread2抢到锁....setB
thread2 -1 -1.0
thread1抢到锁..setA
thread2 3 4.0
thread1 3 4.0
thread2抢到锁....setB
thread1 1 2.0
thread2 1 2.0
thread1抢到锁..setA
thread2 3 4.0
thread1 3 4.0
thread2抢到锁....setB
thread1 1 2.0
thread2 1 2.0
thread1抢到锁..setA
thread2 3 4.0
thread1 3 4.0
thread1 1 2.0

**  但是**,如果将 
 System.out.println(Thread.currentThread().getName() + "抢到锁....setA");
 和
 System.out.println(Thread.currentThread().getName() + "抢到锁....setB");

放到 synchronized(c) 块里面,那么结果之一:
thread1抢到锁..setA
thread1 -1 -1.0
thread1 1 2.0
thread2抢到锁....setB
thread2 1 2.0
thread2 3 4.0
thread1抢到锁..setA
thread1 3 4.0
thread1 1 2.0
thread2抢到锁....setB
thread2 1 2.0
thread2 3 4.0
thread1抢到锁..setA
thread1 3 4.0
thread1 1 2.0
thread2抢到锁....setB
thread2 1 2.0
thread2 3 4.0

可能 输出有先后,但是 至少 thread1,thread2的输出之间,不会相互干扰。。。

我仔细观察了,上面的结果,虽然相互干扰,但是也不会出错,但是为什么 会这样呢? 既然 已经进入 thread1了,thread2怎么还能得到锁呢。。如果这样的话,synchronized(obj)还有啥意思啊(obj不一定是this)? 。实在没搞懂啊。再次麻烦各位帮忙。

总共就1个币,谅解哈。

  • 写回答

6条回答 默认 最新

      报告相同问题?

      相关推荐 更多相似问题

      悬赏问题

      • ¥15 苹果手机删除了qq软件,qq文件怎么恢复
      • ¥20 用mips 人力编程排序问题(能在mars按要求运行)
      • ¥15 Verilog小型神经网络(单层反馈神经网络)
      • ¥15 设计一个数字钟,实现时分秒的显示
      • ¥15 Clion使用头文件链接两个cpp
      • ¥15 51单片机无法触发外部中断问题
      • ¥15 基于半监督,无监督的调制识别
      • ¥15 cst求 阵列 rcs 时候 频域 时域求解器 应该怎样设置 才让两者 计算结果 相似 请附图
      • ¥15 关于#51单片机#的问题:大家帮我看一下为什么我的计时器数字一直不稳定
      • ¥15 Qt 在应用程序里总是有[PREVIEW] recv window msg, name:(Qt5QWindowIcon) hwd:(287097a)等信息不断输出,怎么解决