public class T {
  public static synchronized void main(String[] a) {
    Thread t = new Thread() {
      @Override
      public void run() {
        t();
      }
    };
    t.run();
    System.out.print(1);
  }  static synchronized void t() {
    System.out.print(2);
  }
}

解决方案 »

  1.   

    此回复为自动发出,仅用于显示而已,并无任何其他特殊作用
    楼主【tteesstt】截止到2008-07-07 10:00:26的历史汇总数据(不包括此帖):
    发帖的总数量:85                       发帖的总分数:4700                     
    结贴的总数量:85                       结贴的总分数:4700                     
    无满意结贴数:0                        无满意结贴分:0                        
    未结的帖子数:0                        未结的总分数:0                        
    结贴的百分比:100.00%               结分的百分比:100.00%                  
    无满意结贴率:0.00  %               无满意结分率:0.00  %                  
    敬礼!
      

  2.   

    21你是直接调用run,又不是多线程运行的,肯定按照顺序执行啊
      

  3.   

    把 t.run() 改成 t.start()的结果呢?
      

  4.   

    21
    下面的程序全部是由同步化(synchronized)的静态方法组成的。那么它会打印出什么呢?在你每次运行这段程序的时候,它都能保证会打印出相同的内容吗?
    public class T {
    public static synchronized void main(String[] a){
    Thread t = new Thread(){
    public void run(){
    t();
    }
    };
    t.run();
    System.out.print(1);
    } static synchronized void t() {
    System.out.print(2);
    }}在多线程程序中,通常正确的观点是程序每次运行的结果都有可能发生变化,但是上面这段程序总是打印出相同的内容。在一个同步化的静态方法执行之前,它会获取与它的 Class 对象相关联的一个管程(monitor)锁[JLS 8.4.3.6]。所以
    在上面的程序中,主线程会在创建第二个线程之前获得与 T.class 相关联的那个锁。只要主线程占有着这个锁,第二个线程就不可能执行同步化的静态方法。具体地讲,在 main 方法打印了 1 并且执行结束之后,第二个线程才能执行 t 方法。只有当主线程放弃那个锁的时候,第二个线程才被允许获得这个锁并且打印 2。根据以上的分析,我们似乎可以确信这个程序应该总是打印 12。但是这里有一个小问题:当你尝试着运行这个程序的时候,你会发现它总是会打印 21。到底发生了什么呢?
    正如它看起来的那样奇怪,这段程序并不是一个多线程程序。不是一个多线程程序?怎么可能呢?它肯定会生成第二个线程啊。喔,对的,它确实是创建了第二个线程,但是它从未启动这个线程。相反地,主线程会调用那个新的线程实例的 run 方法,这个 run 方法会在主线程中同步地运行。由于一个线程可以重复地获得某个相同的锁 [JLS 17.1] ,所以当 run 方法调用 t 方法的时候,主线程就被允许再次获得与 T.class 相关联的锁。t 方法打印了 2 并且返回到了run 方法,而 run 方法又返回到 main 方法。最后,main 方法打印了 1,这就解释了我们看到的输出结果是怎么来的。
    要订正这个程序很简单,只需将 t.run 改写成 t.start。这么做之后,这个程序就会如你所愿的总是打印出 12 了。
    这个教训很简单:当你想调用一个线程的 start 方法时要多加小心,别弄错成调用这个线程的 run 方法了。遗憾的是,这个错误实在是太普遍了,而且它可能很难被发现。或许这个谜题的教训应该是针对 API 的设计者的:如果一个线程没有
    一个公共的 run 方法,那么程序员就不可能意外地调用到它。Thread 类之所以有一个公共的 run 方法,是因为它实现了 Runnable 接口,但是这种方式并不是必须的。另外一种可选的设计方案是:使用组合(composition)来替代接口继承(interface inheritance),让每个 Thread 实例都封装一个 Runnable。组合通常比继承更可取。这个谜题说明了上述的原则甚至对于接口继承也是适用的。
      

  5.   

    start为线程入口,通过它启动线程,其源代码 
    public synchronized void start() { 
    if (started) 
    throw new IllegalThreadStateException(); 
    started = true; 
    group.add(this); 
    start0(); 
    } run为实际代码执行段 如果在程序中直接调用run的话就变成了普通方法,因为没有将它加入到线程组中 如果你用run,就会发现程序会假死,因为它只是一个常规方法的调用,还是用的main这个线程
      

  6.   

    http://hi.baidu.com/johnsoncr/blog/item/71b93b012af6c700738da5c2.html