理解java中的同步

时间:2013-07-31 08:52:04

标签: java multithreading

为什么通常线程样本会在synchronized块中放入如此多的代码。根据我的理解,在以下情况中,synchronized仅用于锁定b等待并通知:

主类ThreadA:

class ThreadA {
      public static void main(String [] args) {
         ThreadB b = new ThreadB();
         b.start();

         synchronized(b) {
            try {
               System.out.println("Waiting for b to complete...");

              b.wait();
           } catch (InterruptedException e) {}
           System.out.println("Total is: " + b.total);
           System.out.println(Thread.currentThread().getName());

        }
     }
  }

和类ThreadB:

class ThreadB extends Thread {   
     int total;     
     public void run() {
        synchronized(this) 
        {
           System.out.println();
           for(int i=0;i<100;i++) 
           {
               System.out.println(Thread.currentThread().getName());
              total += i;
           }
           notify();
        }
     }
  }

如果我只在wait块中添加notifysynchronized,会有什么变化:

class ThreadA {
      public static void main(String [] args) {
         ThreadB b = new ThreadB();
         b.start();
            try {
               System.out.println("Waiting for b to complete...");

                synchronized(b) {   b.wait();}
           } catch (InterruptedException e) {}
           System.out.println("Total is: " + b.total);
           System.out.println(Thread.currentThread().getName());


     }
  }

2 个答案:

答案 0 :(得分:3)

  

根据我的理解,在以下情况中,synchronized仅用于锁定b等待并通知

你的理解是错误的。

synchronized也用于:

  • 相互排斥,以确保一次只有一个线程执行由特定监视器“保护”的代码
  • 确保跨线程的内存访问是正确的(一个线程看到另一个线程所做的更改)
  

如果我只是在同步块中等待并通知,那么会发生什么变化:

在这种特殊情况下,它将根据竞争条件产生差异 - 在原始代码中,如果新的thread在之前开始执行,则在原始代码中达到同步块线程,它将不会达到“等待b完成”,直到第二个线程完成...此时它将永远阻塞wait

请注意,在Thread监视器上等待非常糟糕,因为wait/notify在内部使用Thread

简而言之,您使用的示例以各种方式开始时很糟糕 - 但同步 不仅仅用于wait/notify

答案 1 :(得分:0)

请注意,total += i 是Java中的原子操作。所以你必须同步这个结构。

您还必须同步notify()和wait(),因为它们的锁是在内部处理的。