基本概念喔。
俺们来看看你的代码:
<<
    TestSynchronized t1 = new TestSynchronized("t1");
    TestSynchronized t2 = new TestSynchornized("t2");
    t1.start();
    t1.ptr();
    t2.ptr();
>>
有几个自定义线程在运行?2个:
(1) MAIN线程,就是你的main方法运行的哪个线程;
(2) t1线程,你使用t1.start()启动的线程;这两个线程可以并发地运行。
main线程运行 t1.ptr() 和 t2.ptr() 这两个方法,当然是串行运行(序列地运行),先执行完t1.ptr(),再执行t2.ptr()。所以输出结果得到:
<<
main:10---main:19 // t1.ptr()输出
main:10---main:19 // t2.ptr()输出
>>
而t1线程也在并发运行,输出:
<<
t1:1---t1:10 // t1.run()输出。
>>

解决方案 »

  1.   

    对了,忘记给你解释synchronized的问题了。:)
    两个线程main线程和t1线程执行的方法都是sycnrhonized的。进入monitor之后,这两个线程会竞争t1对象的锁。而与t2对象没有关系。
    看看你的输出情况:
    首先输出main10-main19:说明main线程的t1.ptr()方法竞争到了同步锁,开始输出,此时的t1线程被阻塞。t1.ptr()执行完成之后,开始执行t2.ptr(),而此时t1.run()得到同步锁开始执行run()方法,所以开始main10-main19和t1:1-t1:10开始交互输出。
    交互输出的是:t2.ptr() 和 t1.run()
      

  2.   

    那么后面加static后的运行,当如何解释?
    不再阻塞了吗?
      

  3.   

    加了static之后,当然就不存在上面的问题了。你看:
    public synchronized void run() {...}
    public static synchronized vdoi ptr() {...}run()方法的锁是加在TestSynchronized实例上的,上例中是你的t1。
    而ptr()方法是类方法,锁加在TestSynchronized.class类实例之上。
    run()和ptr()不需要竞争同一把锁了。你可以这么看待这两个方法:
    public synchronized void run() {..} 等价于:
    ------------------------------------------
    public void run() {
        synchronized(this) {
           .........
        }
    }
    而public static synchronized void ptr() {...} 等价于:
    ----------------------------------------------
    public static void ptr() {
        synchronized(TestSynchornized.class) {
           ........
        }
    }
    看,不用竞争同一个对象锁了。