class DualSynch{
public void f(int flag) {
synchronized (this) {
System.out.println("f()" + flag);
}
}
}
public class Test {
public static void main(String[] args) {
final DualSynch ds = new DualSynch();
new Thread() {
public void run() {
int i = 0;
while(i ++ <2){
ds.f(1);
try {
sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}.start();
new Thread(){
public void run() {
ds.f(2);
}
}.start();
}
}
既然sleep()不释放锁,为什么这个程序运行结果会出现f(1) f(2) f(1)呢?在线程一sleep时,线程二得到了锁并且调用了f()方法多线程

解决方案 »

  1.   

    Thread 1 sleep的时候根本就没有占据锁。因为sleep的方法在同步关键字外面执行的。将sleep放到同步关键字中
        public void f(int flag) {
            synchronized (this) {
                System.out.println("f()" + flag);
                try {
                    Thread.sleep(10000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
      

  2.   

    sleep方法只是让线程睡眠一段时间,单纯的让线程休息会儿。
    跟“锁”没有直接没有关系。
      

  3.   

    sleep方法只是让线程睡眠一段时间,单纯的让线程休息会儿。
    跟“锁”没有直接没有关系。

    可是java编程思想这本书里和网上都说sleep()不释放锁,wait()会释放锁
      

  4.   

    2楼正确的。 sleep(10000) ,我改了一下,sleep (1000), 会出现下面的结果:
    f()1
    f()1
    f()2
      

  5.   

    有可能是这样的情况,当你退出上锁的那个方法的时候当前线程的执行时间已经用完了,那么CPU就把执行的权利交给了另一个线程,因为你前一个线程已经退出来了 那么当前的线程就可以去执行那个方法了。
     你可以这样去试试,在上锁的方法中打印一串字符,用for循环一个字符一个字符的打印,没打印一个字符休眠一会,到后面看看输出的字符 会不会乱,就能看出来他到底是不是有释放锁了
      

  6.   

    整个程序没什么难理解的
    首现启动了两个线程,宏观上说这两个线程没什么关系。
    启动第一个线程调用了 ds.f()方法,调用之后小憩1s
    启动第二个线程调用了 ds.f() 方法这两个线程本身上是没什么关系的,仅是在调用ds.f()的方法时,需要获取ds这个对象的锁
    启动这两个线程,并不代表线程1就先执行,这两个线程谁先执行是不确定的,谁先执行并调用ds.f()方法就先得到ds对象的锁。(备注:不要误认为是线程得到了锁,只是在调用ds.f()方法时,才会需要ds对象的锁。所以while循环中也不意味着会一直执行下去),另外 sheep()那个方法和锁没任何关系。无非使线程二获取锁的概率增大。
      

  7.   

    知道原因了,我的循环写得有问题,每循环一次都重新得到锁释放锁,所以出现那种现象。sleep()确实不会释放锁