When a thread has yielded as a result of yield(), it releases its locks.
                                                                        
When a thread is sleeping as a result of sleep(), it releases its locks.这两人句话有什么不对?
对于sleep,api说不会放弃监视器,似乎是指锁,但我做了个例子,发现还是会放弃啊。到底怎么回事。public class Threads4 {
    public static void main(String[] args) throws Exception{
       class Mythread implements Runnable{
           Threads4 t4;
           Mythread(Threads4 t4) {
              this.t4=t4;
           }           public void run() {
               System.out.println("start "+Thread.currentThread().getId());
               try {
                   t4.go();
               } catch (Exception e) {
                   e.printStackTrace();
               }               System.out.println("end "+Thread.currentThread().getId());
           }
       }
        Threads4 t4=new Threads4();        Thread t1=new Thread(new Mythread(t4));
        Thread t2=new Thread(new Mythread(t4));
        t1.start();
        Thread.sleep(2000);
        t2.start();
    }    public synchronized void  go(){
        System.out.println(Thread.currentThread().getId());
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
        }
    }}

解决方案 »

  1.   

    注释掉main方法中的Thread.sleep()看得更明显一点。
    sleep方法是没有放弃锁的,打印完start 8之后打印8之前的那段时间就是在等待释放锁。
      

  2.   

    这两句话都不对吧,这两个都不释放锁,
    你的程序中你在sleep后面加一条输出语句你会看得更清楚,它到底释放锁了吗,你会看到控制台中每个go()都会连续打印两条语句
      

  3.   

    改成如下的看着是更清楚了:
    public class Threads4 {
        public static void main(String[] args) throws Exception{
           class Mythread implements Runnable{
               Threads4 t4;
               Mythread(Threads4 t4) {
                  this.t4=t4;
               }           public void run() {
                  t4.go();
               }
           }
            Threads4 t4=new Threads4();        Thread t1=new Thread(new Mythread(t4));
            Thread t2=new Thread(new Mythread(t4));
            t1.start();
    //        Thread.sleep(2000);
            t2.start();
        }    public synchronized void  go(){
            System.out.println("start go in thread :"+Thread.currentThread().getId());
            try {
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
            }        System.out.println("end go in thread :"+Thread.currentThread().getId());
        }}
    但是,对于yield,还有个疑问,看了http://www.diybl.com/course/3_program/java/javajs/20090407/164526.html#这篇文章,算是有了个答案,但还有个小小疑问,既然是yield用来让其它线程有机会来执行,自己放弃本次时间片。它不放弃锁怎么让其它线程来执行呢?是否yield的线程就不应该来访问同步方法,或可解释这个问题
      

  4.   


    是啊 而且书上写的也不一定对  JDK现在都7.0 beta了 以前可以重现的线程安全的错误 现在都出现不了
    也就是说  书上曾经对的地方 现在也许不对了 还是自己搞搞例子  进步快啦
      

  5.   

    在实际应用中,wait()方法必须在同步方法或者同步块中调用,因为只有获得这个共享对象,才可能释放它。sleep()方法是使一个线程的执行暂时停止的方法,楼主是不是搞混了!
      

  6.   

    sleep和wait都是使线程暂时停止执行的方法 
    ,但它们有很大的不同,sleep是线程类Thread 的方法, 
    它是使当前线程暂时睡眠,可以放在任何位置。 
    而wait是Object类的方法,它是使当前线程暂时放弃对象的使用权进行等待, 
    必须放在同步方法或同步块里。 
    Sleep使用的时候,线程并不会放弃对象的使用权,即不会释放对象锁,所以在同步方法或同步块中使用sleep,一个线程访问时,其他的线程也是无法访问的。 
    而wait是会释放对象锁的,就是当前线程放弃对象的使用权,让其他的线程可以访问。 
    线程执行wait方法时,需要另一个线程调用notify进行唤醒。 
    而sleep只是暂时休眠一定时间,时间到了之后,自动恢复运行,不需另外的线程唤醒。
      

  7.   

      楼主,我拿你代码测试过了,还是sleep还是不会放弃锁。至于你说的yield()的有点道理。yield()只是线程放弃当前的执行机会,进入就绪状态,并没有放弃锁,等到下次的时间片到来时,该线程又继续执行起来。从测试来看,确实是这样的结果。
      如果真是这样的话,那yield()的方法的意义何在?
      

  8.   

      在网上查了资料之后
      yield() 方法的解释之后更加疑惑了。。
     yield() 使得线程放弃当前分得的 CPU 时间,但是不使线程阻塞,即线程仍处于可执行状态,随时可能再次分得 CPU 时间。调用 yield() 的效果等价于调度程序认为该线程已执行了足够的时间从而转到另一个线程。yield()只是使当前线程重新回到可执行状态,所以执行yield()的线程有可能在进入到可执行状态后马上又被执行。sleep()可使优先级低的线程得到执行的机会,当然也可以让同优先级和高优先级的线程有执行的机会;yield()只能使同优先级的线程有执行的机会。
        正如楼主说的 如果具有yield()的线程进入同步代码块之后,根本就没有释放对象锁,它的效果也只等同于 wait(时间片长度) 而已。
       不知道我理解是否正确。如果正确的话,那yield()有什么作用?
       请高手帮忙解释下
       期待。。关注
      

  9.   

    调用yield就不能获得所,它是让给同优先级的线程cup使用权,使用yield就不能用锁把它锁住
      

  10.   

    为什么加synchronizic呢,加了当然会同步了阿,去掉之后sleep确实释放锁了啊。