方法a这样声明,表示一个线程只有获取了当前Test实例的锁时才可以执行apublic synchronized void a(){
  System.out.println("aa");
  }方法b也是一样,它要求的也是同样的锁main方法所在的线程执行b,就已经获得了this对应的锁,所以它可以执行方法a,就相当于你家的所有的门都使用同一把钥匙,那么你只要带一把钥匙就可以了。

解决方案 »

  1.   

    真搞不懂,现在越来越多的人到论坛里来风言风语,这里是讨论技术问题的,会的就回答问题,不会也谦虚点,老说些不着边际的话很有趣吗?怎么没有线程?你的main方法也是虚拟机在一个线程里执行的,不管执行什么程序,虚拟机里本身就有自己的多线程环境。楼主只是写个简单的例子来问这个问题,难道非要让人家把多线程的代码全部贴出来?
      

  2.   

    楼上的搞什么啊,MAIN()产生的是精灵线程,和用户线程2回马子事情,不懂不要装懂,更不要误倒别人.
    真怀疑你懂不懂什么synchronized的具体含义和用法.
    不写用户多线程怎么看的出是同步还是异步的?
      

  3.   

    >>MAIN()产生的是精灵线程精灵线程?你是指Daemon thread吗?拜托不要用你不懂的名词来吓人,看看下面,这是Thread类的文档说的:When a Java Virtual Machine starts up, there is usually a single non-daemon thread (which typically calls the method named main of some designated class). The Java Virtual Machine continues to execute threads until either of the following occurs: The exit method of class Runtime has been called and the security manager has permitted the exit operation to take place. 
    All threads that are not daemon threads have died, either by returning from the call to the run method or by throwing an exception that propagates beyond the run method. 恰恰相反,执行main方法的是一个非“精灵线程”。而且你所说的关系也是错误的,不是main方法产生线程,而是虚拟机产生一个线程来调用main方法。Daemon thread也可以叫后台线程,或守护线程,这种线程一般负责执行后台任务,我猜测(只是猜测)在有些虚拟机的实现中,垃圾收集可能是在一个daemon thread中进行的。虚拟机在所有非daemon thread执行结束后退出,也就是说,如果用户程序没有启动别的线程,那么main方法退出后,虚拟机就会退出。一个特殊的情况是AWT或Swing程序,因为其中有一个线程用于事件分发(event dispatch)和重画(repaint),关于这个问题,可以参考下面的文章,讲的是AWT线程问题http://java.sun.com/j2se/1.4.2/docs/api/java/awt/doc-files/AWTThreadIssues.html>>不懂不要装懂,更不要误倒别人我原来对daemon thread还真的是一知半解,现在比较清楚了。sunjie1981,你清楚了吗?现在你告诉我,是谁在误导别人?奉劝你一句:没有把握的话,不要说那么满。>>真怀疑你懂不懂什么synchronized的具体含义和用法我当然懂,如果对这个java的基本问题没有比较清楚的认识,我是不会来贸然回答这个问题的。楼主的疑问是,两个方法都同步了,为什么可以在一个方法中执行另一个。我只想用比较形象、简单的方式让他明白这个问题,一个线程拥有了一个对象对应的锁后,当然可以执行别的在同一个对象上同步的方法。我不想说一大堆synchronized的东西,那样可能会更糊涂。如果你对这个问题不是很清楚,可以从这里http://java.sun.com/docs/books/vmspec/下载 Java Virtual Machine Specification,其中 2.19 节介绍了线程还可以从这里http://java.sun.com/docs/books/jls/下载 Java Language Specification,其中12.1 节讲了虚拟机启动,第17章讲的是线程和锁>>不写用户多线程怎么看的出是同步还是异步的我已经说过了,一段代码用synchronized做了同步处理,就说明它准备应用于多线程环境。如果你看不出来,只能说明你自己有问题。诚然,synchronized方法或代码也可以在单线程环境(只是指用户应用是单线程,而不是指虚拟机环境)执行,但synchronized不仅仅是个符号,线程要执行这个方法,还是要获得对应的锁,这些都是要耗费资源的。说点题外话,我不满的是你这种态度。如果你懂,就让别人也懂;如果不懂,至少不要乱说。
      

  4.   

    应该两个方法都是用this锁,就是Test的个对象。
      

  5.   

    to  chongkai() :
    真不知道怎么说你了,请弄清JVM的作用,JVM是调度线程的.
    如果你说MAIN()产生的不是精灵线程,那算什么?难道是用户线程?JAVA就分2种线程类别.还有你说单线程可以用synchronized,这个我不否认.
    我最终意思就是说楼主举例不到位.
      

  6.   

    When a Java Virtual Machine starts up, there is usually a single non-daemon thread (which typically calls the method named main of some designated class). The Java Virtual Machine continues to execute threads until either of the following occurs:
    当Java虚拟机启动时、通常会有一个非daemon线程(就是MAIN方法)、Java虚拟机持续执行之直到:
    The exit method of class Runtime has been called and the security manager has permitted the exit operation to take place. 
    All threads that are not daemon threads have died, either by returning from the call to the run method or by throwing an exception that propagates beyond the run method.
    运行时类退出并且得到安全管理的允许、
    所有非daemon线程终止、或者执行完毕、抛出异常。
      

  7.   

    to sunjie1981():>>真不知道怎么说你了这句话好像我来说比较好。>>请弄清JVM的作用,JVM是调度线程的JVM的作用?JVM是调度线程的?很不幸,JVM绝不仅仅只是个线程调度器,如果连这个都要解释,那我选择不解释。>>如果你说MAIN()产生的不是精灵线程,那算什么?难道是用户线程?我已经说的很清楚了,暂且不谈精灵线程,至少不是什么main产生线程,而是一个线程来调用main方法。你的概念就是错的!你真的弄懂什么是所谓的精灵线程了吗?我贴的英文文档你都看了吗?When a Java Virtual Machine starts up, there is usually a single non-daemon thread (which typically calls the method named main of some designated class).这句话说的还不清楚吗?它明明白白地说了,是一个non-daemon thread 调用main方法,你还是要咬着你的“精灵线程”不放。我们动动脑子,看清楚了,想好了再说好不好?>>JAVA就分2种线程类别如果要分类,我想分为系统线程和用户线程比较好,前者是虚拟机启动的线程,后者是用户自己启动的线程。这和是否是daemon线程没有关系,调用main方法的线程是系统线程,但它不是daemon;我自己创建一个线程,可以用setDaemon方法来将它设置为daemon。从另一个角度,可以将线程分为deamon和non-daemon两种。但这是两种完全不同的分类。Any thread may be ed as a daemon thread. When code running in some thread creates a new Thread object, that new thread is initially ed as a daemon thread if and only if the creating thread is a daemon thread. A program can change whether or not a particular thread is a daemon thread by calling the setDaemon method in class Thread. The Java virtual machine initially starts up with a single nondaemon thread, which typically calls the method main of some class. The virtual machine may also create other daemon threads for internal purposes. The Java virtual machine exits when all nondaemon threads have terminated (§2.17.9).
      

  8.   

    试试我的翻译功夫When a Java Virtual Machine starts up, there is usually a single non-daemon thread (which typically calls the method named main of some designated class). The Java Virtual Machine continues to execute threads until either of the following occurs: 当 Java 虚拟机启动时,通常有一个非守护线程(它一般调用某个指定类的名为 main 的方法)。Java 虚拟机持续运行线程,直到发生以下某种情形:The exit method of class Runtime has been called and the security manager has permitted the exit operation to take place. Runtime 类的 exit 方法被调用,并且安全管理器允许执行 exit 操作。All threads that are not daemon threads have died, either by returning from the call to the run method or by throwing an exception that propagates beyond the run method. 所有非守护线程死亡(从 run 方法的调用返回,或抛出了一个异常,并且该异常传播到 run 方法之外)。Any thread may be ed as a daemon thread. When code running in some thread creates a new Thread object, that new thread is initially ed as a daemon thread if and only if the creating thread is a daemon thread. A program can change whether or not a particular thread is a daemon thread by calling the setDaemon method in class Thread. The Java virtual machine initially starts up with a single nondaemon thread, which typically calls the method main of some class. The virtual machine may also create other daemon threads for internal purposes. The Java virtual machine exits when all nondaemon threads have terminated (§2.17.9).任何线程都可以被标记为守护线程。当在某个线程中运行的代码创建新的 Thread 对象时,当且仅当创建线程的线程是守护线程,新线程最初被标记为守护线程。程序可以通过调用 Thread 类中的 setDaemon 方法,将特定线程改变为守护线程或非守护线程。Java 虚拟机最初启动时有一个非守护线程,该线程一般调用某个类的 main 方法。虚拟机也可以为内部用途创建其它守护线程。Java 虚拟机在所有非守护线程结束后退出。
      

  9.   

    楼上的不厚道,这个回答的已经很明确了,也没什么东西,倒是两个人的辩论倒是让人打开眼界,
    chongkai() 佩服!楼主的答案不就是这个吗,让我重贴一次! 
    方法a这样声明,表示一个线程只有获取了当前Test实例的锁时才可以执行apublic synchronized void a(){
      System.out.println("aa");
      }方法b也是一样,它要求的也是同样的锁main方法所在的线程执行b,就已经获得了this对应的锁,所以它可以执行方法a,就相当于你家的所有的门都使用同一把钥匙,那么你只要带一把钥匙就可以了。