源码如下: 
public class TestThread implements Runnable{ 
 
    int b =100 ; 
     
    public synchronized void m1() throws InterruptedException{ 
        b=1000; 
        Thread.sleep(5000); 
        System.out.println("m1(): b="+b); 
    } 
 
    public synchronized void m2() throws InterruptedException{ 
        Thread.sleep(2500); 
        System.out.println("-------------"); 
        b=2000; 
    } 
 
    @Override 
    public void run() { 
        // TODO Auto-generated method stub 
        try{ 
          m1();     
        }catch (Exception e) { 
            // TODO: handle exception 
            e.printStackTrace(); 
        } 
    } 
     
    /** 
     * @param args 
     */ 
    public static void main(String[] args) throws Exception{ 
        // TODO Auto-generated method stub 
          TestThread tr = new TestThread(); 
          Thread tt = new Thread(tr); 
          tt.start(); 
           
          tr.m2(); 
          System.out.println("主线程 : b="+tr.b); 
//          Thread.sleep(1000); 
//          System.out.println("主线程 : b="+tr.b); 
           
          Thread.sleep(10000); 
          System.out.println("最后结果 : b="+tr.b); 
 
    } 
 

 
 
运行结果: 
    ------------- 
主线程 : b=1000 
m1(): b=1000 
最后结果 : b=1000 
 
这里不明白的是, synchronized的作用不是不同线程只能在同一个对象上加一把锁么?既然一个对象只能有一把锁的话,  那用两个synchronized方法同步访问还是有问题,还不如直接把对象给锁住呢 

解决方案 »

  1.   

    syschronized的锁定该对象,指的是TestThread类的对象吧, 那按照这样理解的话,出现这样的结果: 
     
       -------------  
    主线程 : b=1000  
    m1(): b=1000  
    最后结果 : b=1000  
     
    那分析下执行的顺序: 
     
    1. 先是主线程m2()方法执行完"------------------"并将b值由100改为2000,然后时间片结束。 
    2. 执行线程2的m1()方法将b值由2000改为1000, 然后回到主线程。 
    3. 执行主线程的 System.out.println("主线程 : b="+tr.b), 得到 主线程 : b=1000  
    4. 然后继续执行线程2的m1()方法, 打印 m1(): b=1000  
    5. 最后执行主线程,打印 最后结果 : b=1000  
     
    应该是这样的执行结果,  但是我有一个疑问, 这样由CPU进行线程间的切换的话, 由于m1()和m2()方法都加了锁,那这两个方法在执行的时候tr这个对象应该是被锁住了啊, 既然是锁住的话,那么如果CPU从一个线程对象切换到另外一个线程对象,用的是同一个TestThread对象, 难道不会重复的加锁么? 比如从主线程的m2()切换到线程2的m1(), 那主线程的m2()加在tr上的锁怎么办?
     请指教. 
      

  2.   

    先运行的tr.m2();
    再执行的m1()
    tt.start(); 不会马上执行线程,只是放线程池中等待CUP来调度。
    先执行的tr.m2();取得对象锁
    当tr.m2();执行完成后,m1()取得锁执行。
    所以结果都是b=1000 
      

  3.   

    不会重复加锁,如果是,那么死锁就会像大宝一样,天天见你的理解有误,这里不是对tr对象进行加锁,而是获取tr对象锁。
    意思可以说,我要用tr,得先拿到tr的锁(或者说是钥匙),才能使用。所以怎么可能会重复加锁呢,锁(钥匙)只有一个,谁拿在手里,谁先用,用完归还,没拿到的线程就等待。线程2没有获取到tr对象锁,他会等待直到主线程从m2()方法执行返回tr锁,然后再获取tr对象锁。
      

  4.   

    你可以用Thread.currentThread().yield();来保证tt先执行。实际上你要表现明显的多线程应该再写一个线程来操作b。一个线程不明显。
      

  5.   


    意思是说, 只要执行tr的使用了sychronized关键字的方法,tr对象上就会有锁,无论哪个线程执行都需要获得该锁的钥匙么?
      

  6.   

    en zhege doushuochabuduole a
      

  7.   

    为什么是先执行tr.m2(),再执行的m1()?是不是也有可能先执行m1()?高手指教一下
      

  8.   

     但是我有一个疑问, 这样由CPU进行线程间的切换的话, 由于m1()和m2()方法都加了锁,那这两个方法在执行的时候tr这个对象应该是被锁住了啊, 既然是锁住的话,
    汗 m2执行完 不是释放锁了