下面这段程序到底是锁定的tt对象呢?还是分别锁定的inc和dec对象呢?public class ThreadTest {
private int j; public static void main(String args[]) {
ThreadTest tt = new ThreadTest();
Inc inc = tt.new Inc();
Dec dec = tt.new Dec();
for (int i = 0; i < 2; i++) {
Thread t = new Thread(inc);
t.start();
t = new Thread(dec);
t.start();
}
} private synchronized void inc() {
j++;
System.out.println(Thread.currentThread().getName() + "-inc:" + j);
} private synchronized void dec() {
j--;
System.out.println(Thread.currentThread().getName() + "-dec:" + j);
} class Inc implements Runnable {
public void run() {
for (int i = 0; i < 100; i++) {
inc();
}
}
} class Dec implements Runnable {
public void run() {
for (int i = 0; i < 100; i++) {
dec();
}
}
}
}

解决方案 »

  1.   

       synchronized 加在方法前是说只能容许单个线程进入这个方法 private synchronized void inc() {
            j++;
            System.out.println(Thread.currentThread().getName() + "-inc:" + j);
        }
      

  2.   


    private synchronized void inc() {
            j++;
            System.out.println(Thread.currentThread().getName() + "-inc:" + j);
        }
    等价于:
    private  void inc() {
            synchronized(this){
               j++;
               System.out.println(Thread.currentThread().getName() + "-inc:" + j);
            }
        }
    也就是说,是锁定tt对象
      

  3.   

    锁定tt的inc和dec方法,不锁定tt对象这样是不等价的,你可以在synchronized(this)之前加上System.out.println()就知道了
    synchronized void inc()是锁定方法,只有一个线程能进入方法
    synchronized(this)是锁定对象,只有一个线程能使用对象,但是多个线程能同时进入inc方法,只是在synchronized(this)处发生解锁等待 
      

  4.   

    而其我看尚学堂马士兵的视频说的也是只锁定对象,不是锁定的方法。哪像下面这段代码锁定的是什么呀??public class Test1 implements Runnable {
                    public void run() {
                        synchronized(this) {
                            try {
                                System.out.println(System.currentTimeMillis());
                                Thread.sleep(2000);
                                System.out.println(System.currentTimeMillis());
                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            }
                        }
                    }                public static void main(String[] args) {
                        Test1 test=new Test1();
                        for(int i=0;i<10;i++) {
                            new Thread(test).start();
                        }
                    }
                }
      

  5.   

    参考
    http://topic.csdn.net/u/20100514/12/06c5ce11-84a3-42ca-8744-8a83cca0530a.html?seed=1426370052&r=65431300#r_65431300
      

  6.   

    头一回听说还可以锁定方法!Object对象才有锁,方法也有锁?
    你这个例子是在Test1对象实例上加锁。
    main方法中:
    Test1 test=new Test1();
    for(int i=0;i<10;i++) {
         new Thread(test).start();
    }
    多个Thread共享一个test,test此时就是一个共享资源,因此10个Thread对象共享一个test,在test实例上加锁,同时只有1个Thread对象可以获得锁得以执行,因此这10个线程可以做到互斥。
    你可以在代码里面输出线程的名字进行查看,只有一个执行完毕以后,下一个才开始执行。
      

  7.   

    头一回听说还可以锁定方法!Object对象才有锁,方法也有锁?
    你这个例子是在Test1对象实例上加锁。
    main方法中:
    Test1 test=new Test1();
    for(int i=0;i<10;i++) {
         new Thread(test).start();
    }
    多个Thread共享一个test,test此时就是一个共享资源,因此10个Thread对象共享一个test,在test实例上加锁,同时只有1个Thread对象可以获得锁得以执行,因此这10个线程可以做到互斥。
    你可以在代码里面输出线程的名字进行查看,只有一个执行完毕以后,下一个才开始执行。
      

  8.   

    锁定的意思是指这个方法拿到了某个对象的锁,这样其他方法想再次获得这个对象的锁就会进入同步。synchronized放在方法上,拿到的调用这个方法的对象的锁。
    和在里面用synchronied(this)是一个效果的
      

  9.   


    Inc inc = tt.new Inc();
    Dec dec = tt.new Dec();内部类对象inc和dec的内部有一个私有成员,用来保存其外围类的实例,即tt。对应的run方法中调用的inc()和 dec()方法其实就是tt.inc()和 tt.dec()。所以两个线程获得对象锁是tt的锁。
      

  10.   

    无论synchronized关键字加在方法上还是对象上,他取得的锁都是对象,而不是把一段代码或函数当作锁――而且同步方法很可能还会被其他线程的对象访问。 
      

  11.   

    是不一样的,获得锁的时点和地址是不一样的
    一个简单的例子
    synchronized void xxx() {
        //一旦线程进入方法,其他线程就要等待

    void xxx() {
        //做一些额外处理
        synchronized(this) {
           //当某个线程进到这里,其他线程才会发生等待,在线程进入之前,多个线程可同时进入方法,处理上面的额外处理,如果没有上面的额外处理,从结果来说,和synchronized void xxx是一样的,但是从锁的角度来说是不一样的
       }
    }
      

  12.   

    从处理结果来说是等价的,从处理获得锁的时点和地址来说是不一样的,因为多线程可能同时进入了方法,只是在synchronized(this)的地方发生等待
      

  13.   

    public synchronized void xxxx() {
        aaaa;
        bbbb;
        cccc;
    }与public void xxxx() {
        synchronized(this) {
            aaaa;
            bbbb;
            cccc;
        }
    }是一样的,没有区别
      

  14.   

    正解,两种写法都表示线程要获得该实例的锁才能运行被synchronized修饰的代码
      

  15.   

    获得锁权限是从synchronized块开始的应该都认同吧,既然如此,synchronized在不同的位置,就是不一样,只不过说结果一样了,但要明白其中是有区别的
    比如有某个入口,入口有两扇门,我们把它分为外门和内门,当锁外门的时候(即synchronized method),人是通不过入口进入里面的(即进不来方法内部),当锁内门的时候(即synchronized(this)),人也是通不过入口进入进入里面的,从结果来说,是一样的,都是人不能通过入口进入里面,但从锁的角度来说,是不一样的,因为锁外面,人还可以进入到外门和内门之间。当然,也可以同时锁两扇门,即两个synchronized同时用,结果也是一样的,但从锁的角度来说,也是不一样的,必须先获得第一个锁的权限,才有资格获得第二个所的机会。
    另外,synchronized method的时候,当有线程进入该方法时,其他线程一样可以访问该对象的其他方法,可以自己写代码去test,我就不多说的了,以后可以自己在实践中多多体会。如果只知道的结果而不考虑其中的区别,那就忽略我所说的
      

  16.   

    简单地说是:
    通过 t = new Thread(xx) 后得到的一共4个线程尝试锁住 ThreadTest 对象,某个时刻获得 ThreadTest 对象的锁的话就可以执行 inc () 或 dec () 方法,要弄明白锁住哪个对象,其实你主要关注你需要保护哪个对象的状态(不是方法)。
      

  17.   

    锁定只会是对象,不能是方法,上面的inc和dec都是TestThread类的成员方法,所以锁定的对象应该是该方法所属的对象,即tt。
      

  18.   

    纠正一下我所说的锁方法的说法,是我表达不好,其实我更多的是从底层的编译去考虑,锁只是针对对象而言
    但是我还是坚持synchronized method和synchronized(this)有区别,这是经验告诉了我,我虽然不能很好地解释,我自己查了一下《深入java虚拟机》第二版,第347-353页,上面有说两种的区别,功能上是一致的,即处理结果是一样的,但synchronized method更高效,有兴趣的人自己去看吧
      

  19.   

    根据《深入java虚拟机》的描述,同步方法与同步块只是在字节码上面更加高效。但是我认为虽然在字节码上高效,但是相对于只保护方法中部分代码而言,同步方法的并发性要更差一些。我感觉应该从细粒度上来考虑同步。如果什么都不管只在方法上加个同步关键字,我并不认为效率会高,有时候
    只是这个方法中的部分几行代码需要进行同步处理,并不需要将整个方法锁住。
      

  20.   

    这个高效的问题是在synchronized(this)作用于整个函数的前提下比较的,如果像你所说的,只是某部分synchronized,那就回到我上面所说的现象,如果只是部分synchronized(this),那synchronized method和synchronized(this)在处理结果上就有可能不一样,也就是说synchronized method和synchronized(this)并不一定等价,我也觉得同步方法的并发性不好,我也没想到书中是这样的答案,具体什么样的处理性能更好,这需要具体问题具体分析,我这里只是想说明synchronized method和synchronized(this)是有区别的
      

  21.   

    这个区别仅在于 JVM 指令数量上,对于功能和锁的作用范围是一样的。
      

  22.   

    我觉得synchornized 方法类似于synchornized(this), synchornized(obj)是根据指定对象obj的锁来同步。