synchronized是对象级的同步,而this正好也是对象级的,所以就兼职了.
也可以定义一个专门的同步对象.

解决方案 »

  1.   

    就是持有对象的可见性问题。例如,在一个多线程的应用中,A Thread Class被Main thread多次创建(new)并执行(run),要想同步语句块,持有对象就要被定义为static,如:
    private static Object dummyLock = new Object();
    这样才能保证语句块的同步;使用this则不行了,?因为出现了多个A Thread实例,而每个实例中this指向自己,...自己领会吧
      

  2.   

    是不是共同使用的一个持有对象为多个线程使用同步块提供了锁?即只要有一个线程进入同步块,便取得该持有对象的锁,此时另外欲使用同步块的线程必须等待持有对象解锁?就像bigtimber说的例子里,每个线程分别使用各自的持有对象,线程进入同步块总是能从只为其单独服务的持有对象处取得锁,总是能成功执行,同步目的便达不到?
      

  3.   

    下面是一个小例子,看看不同的持有对象对共享对象操作的影响,结果自己跑一下看看。B是期望结果。
    //Test.java
    public class Test {
      public static void main(String[] args) throws InterruptedException {
        A a1 = new A();
        A a2 = new A(5, 200);
        new Thread(a1).start();
        new Thread(a2).start();
        Thread.sleep(2000);
        System.out.println("================================================");
        B b1 = new B();
        B b2 = new B(5, 200);
        new Thread(b1).start();
        new Thread(b2).start();  }
    }class A implements Runnable {  public static int shareObj = 0;  private int times = 5;
      private long sleep = 100;  A() {}  A(int times, long sleep) {
        this.times = times;
        this.sleep = sleep;
      }  public void run() {
        for (int i = 0; i < times; i++) {
          synchronized (this) {
            System.out.println(Thread.currentThread() + " before executing: " + shareObj);
            try {
              Thread.sleep(sleep);
            }
            catch (InterruptedException ex) {
            }        shareObj++;        System.out.println(Thread.currentThread() + " after executing: " + shareObj);
          }
        }
      }
    }class B implements Runnable {  public static Object locker = new Object();
      public static int shareObj = 0;  private int times = 5;
      private long sleep = 100;  B() {}  B(int times, long sleep) {
        this.times = times;
        this.sleep = sleep;
      }  public void run() {
        for (int i = 0; i < times; i++) {
          synchronized (locker) {
            System.out.println(Thread.currentThread() + " before executing: " + shareObj);
            try {
              Thread.sleep(sleep);
            }
            catch (InterruptedException ex) {
            }        shareObj++;        System.out.println(Thread.currentThread() + " after executing: " + shareObj);
          }
        }
      }
    }