public class TestSync implements Runnable {
  Timer timer = new Timer();
  public static void main(String[] args) {
    TestSync test1 = new TestSync();
    TestSync test2 = new TestSync();
    Thread t1 = new Thread(test1);
    Thread t2 = new Thread(test2);
    t1.setName("t1"); 
    t2.setName("t2");
    t1.start(); 
    t2.start();
  }
  public void run(){
    timer.add(Thread.currentThread().getName());
  }
}class Timer{
  private static int num = 0;
  public synchronized void add(String name){ 
   //synchronized (this) {
    num ++;
    try {Thread.sleep(1);} 
    catch (InterruptedException e) {}
    System.out.println(name+", 你是第"+num+"个使用timer的线程");
  //}
  }
}
-----------------------
输出结果:
t2, 你是第2个使用timer的线程
t1, 你是第2个使用timer的线程为什么是这样的结果?

解决方案 »

  1.   

    你的num只有一个,两个线程共用同一个num,所以输出时自然就是2了,因为两个线程在
    System.out 前都已经执行了
     num ++;
    所以,到ssystem.out时,num成为2了,自然就是2了。当然,你输出的结果不是惟一的,在某些情况下输出结果会是你想要的1 和 2
      

  2.   

    public synchronized void add(String name)这里上锁,锁住的是当前对象。你并不能保证这个方法不被两个对象的同时调用。一般情况下,不会在同步的对象方法里面调用静态变量。这是多线程编程时的原则。如果你实在要用,只能对静态变量上锁。
      

  3.   


    可是方法不是已经被锁起来了吗?一个线程调用完add方法,另一个线程才有机会调用这个方法的啊。
      

  4.   

    你这个是同步方法,作用域是当前对象(无论synchronized关键字加在方法上还是对象上,它取得的锁都是对象,而不是把一段代码或函数当作锁――而且同步方法很可能还会被其他线程的对象访问)。
         TestSync test1 = new TestSync();
         TestSync test2 = new TestSync();
    你new了两个线程对象,Timer timer = new Timer();也等于new了两个,也就是说你的锁不是上在同一个对象里,失去了作用域。你的程序可以这样理解:t1执行num+1变成2进入休眠,t2执行,num+1变成2打印出来,t1再打印出来.我想结果也不是唯一的。
    要实现同步的话,TestSync test1 = new TestSync();一个就OK了,两个THREAD里面都放test1。
      

  5.   

    两个线程使用不同的2个对象,synchronized没意义
    TestSync test1 = new TestSync();
    TestSync test2 = new TestSync();
    Thread t1 = new Thread(test1); //t1锁的是test1.timer
    Thread t2 = new Thread(test2); //t2锁的是test2.timer
    因为锁的是不同的对象,所以不能保证同步,test1.timer和test2.timer分别进行num++,当执行到打印输出的时候,num就是不确定的了
      

  6.   

    synchronized应用于方法,锁起来的是对象。那么看你代码的timer对象,两次start()是针对同一对象的嘛?不是,它生产了两个timer对象。
      

  7.   

    不解释,改成下面的再试一下public static void main(String[] args) {
        TestSync test = new TestSync();
        Thread t1 = new Thread(test);
        Thread t2 = new Thread(test);
        t1.setName("t1"); 
        t2.setName("t2");
        t1.start(); 
        t2.start();
      }
      

  8.   

    必须是对象才能被synchronized修饰,你的private static int num = 0;是肯定不能上锁的。可以重新创建一个静态变量,专门用来管理静态变量同步的问题。你可以参考下面的意思。但是下面的代码很有可能会死锁。所以你很有必要去看看多线程的设计原则。class Timer{
      private static int num = 0;
      private static final Timer temp;
      public synchronized void add(String name){ 
           synchronized (temp) {
            num ++;
           }
            try {Thread.sleep(1);} 
            catch (InterruptedException e) {}
            System.out.println(name+", 你是第"+num+"个使用timer的线程");
      }
    }
      

  9.   


    class Timer{
      private static int num = 0;
      public  void add(String name){ 
          synchronized (Timer.class) {
            num ++;
            try {Thread.sleep(1);} 
            catch (InterruptedException e) {}
            System.out.println(name+", 你是第"+num+"个使用timer的线程");
          }
      }
    }