Thread.sleep()不释放锁吗?

时间:2021-07-20 20:57:43
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()方法

12 个解决方案

#1


标记下,我也不清楚帮顶了

#2


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();
            }
        }
    }

#3


引用 2 楼 shnulaa 的回复:
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();
            }
        }
    }

按你说的改了之后结果还是f(1) f(2)交叉出现

#4


引用 楼主 learsea 的回复:
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()方法

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

#5


引用 4 楼 kiritor 的回复:
Quote: 引用 楼主 learsea 的回复:

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()方法

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

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

#6


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

#7


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

你只循环了两次吧,你循环20次试试

#8


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

#9


这是短暂休眠,可以腾出处理器让别的进程运行,里边填的数字就是休眠的时间(毫秒级)

#10


整个程序没什么难理解的
首现启动了两个线程,宏观上说这两个线程没什么关系。
启动第一个线程调用了 ds.f()方法,调用之后小憩1s
启动第二个线程调用了 ds.f() 方法

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

#11


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

#12


2楼正解,路过

#1


标记下,我也不清楚帮顶了

#2


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();
            }
        }
    }

#3


引用 2 楼 shnulaa 的回复:
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();
            }
        }
    }

按你说的改了之后结果还是f(1) f(2)交叉出现

#4


引用 楼主 learsea 的回复:
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()方法

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

#5


引用 4 楼 kiritor 的回复:
Quote: 引用 楼主 learsea 的回复:

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()方法

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

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

#6


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

#7


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

你只循环了两次吧,你循环20次试试

#8


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

#9


这是短暂休眠,可以腾出处理器让别的进程运行,里边填的数字就是休眠的时间(毫秒级)

#10


整个程序没什么难理解的
首现启动了两个线程,宏观上说这两个线程没什么关系。
启动第一个线程调用了 ds.f()方法,调用之后小憩1s
启动第二个线程调用了 ds.f() 方法

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

#11


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

#12


2楼正解,路过