Thread.sleep 释不释放锁?

HELLFS 2021-03-16 10:13:44
麻烦大佬们 给小弟解释解释 这是什么情况?
拜托大佬解惑 谢谢

现象1:Thread.sleep放在同步代码块中 睡眠10秒

public class ImplementsRunnable implements Runnable {

private int ticketNums = 10;
private boolean flag = true;

@Override
public void run() {
while(flag){
//买票
try {
buy();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

public synchronized void buy() throws InterruptedException {
if(ticketNums <= 0){
flag = false;
return ;
}
//睡10秒
Thread.sleep(10000);
System.out.println(Thread.currentThread().getName() + "拿到了第" + ticketNums-- + "票");
}

public static void main(String[] args) {
ImplementsRunnable implementsRunnable = new ImplementsRunnable();
Thread thread = new Thread(implementsRunnable, "小二");
Thread thread1 = new Thread(implementsRunnable, "小三");
Thread thread2 = new Thread(implementsRunnable, "小四");
Thread thread3 = new Thread(implementsRunnable, "小五");
thread.start();
thread1.start();
thread2.start();
thread3.start();
//打印线程状态
while(true){
if((thread.getState() == Thread.State.TERMINATED) ||
(thread1.getState() == Thread.State.TERMINATED) ||
(thread2.getState() == Thread.State.TERMINATED) ||
(thread3.getState() == Thread.State.TERMINATED)
){
break;
}
System.out.println("thread = " + thread.getState());
System.out.println("thread1 = " + thread1.getState());
System.out.println("thread2 = " + thread2.getState());
System.out.println("thread3 = " + thread3.getState());
System.out.println("------------------------------------");
//一次打印 等待10秒
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}

现象一结果:


现象二:Thread.sleep方法 放在run方法中 执行

public class ImplementsRunnable implements Runnable {

private int ticketNums = 10;
private boolean flag = true;

@Override
public void run() {
while(flag){
//买票
try {
buy();
//睡10秒
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

public synchronized void buy() {
if(ticketNums <= 0){
flag = false;
return ;
}
System.out.println(Thread.currentThread().getName() + "拿到了第" + ticketNums-- + "票");
}

public static void main(String[] args) {
ImplementsRunnable implementsRunnable = new ImplementsRunnable();
Thread thread = new Thread(implementsRunnable, "小二");
Thread thread1 = new Thread(implementsRunnable, "小三");
Thread thread2 = new Thread(implementsRunnable, "小四");
Thread thread3 = new Thread(implementsRunnable, "小五");
thread.start();
thread1.start();
thread2.start();
thread3.start();
//打印线程状态
while(true){
if((thread.getState() == Thread.State.TERMINATED) ||
(thread1.getState() == Thread.State.TERMINATED) ||
(thread2.getState() == Thread.State.TERMINATED) ||
(thread3.getState() == Thread.State.TERMINATED)
){
break;
}
System.out.println(thread.getName() + "线程 = " + thread.getState());
System.out.println(thread1.getName() + "线程 = " + thread1.getState());
System.out.println(thread2.getName() + "线程 = " + thread2.getState());
System.out.println(thread3.getName() + "线程 = " + thread3.getState());
System.out.println("------------------------------------");
//一次打印 等待10秒
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}

现象二执行结果:
...全文
712 11 打赏 收藏 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
skyhitnow 2021-03-30
  • 打赏
  • 举报
回复
方法本身是synchronized,在方法体执行完之前怎么会释放锁呢?如果释放的话怎么保证线程安全?
Zchichi88 2021-03-29
  • 打赏
  • 举报
回复
Sleep( ) 不释放锁,wait( )才释放锁。 第一种方法一直是小二那个线程拿到了票是因为,在同步方法执行的sleep的时候其他线程不可以进入,当他立马运行完sleep释放锁之后,其他线程这时候很难竞争过他,所以一直是小二拿到了资源运行线程。测试基数ticket也比较少,当你写1000张票的时候,可以看得到偶尔有其他线程拿到了资源,买到了票。
qq_39936465 2021-03-18
  • 打赏
  • 举报
回复
引用 楼主 HELLFS 的回复:
麻烦大佬们 给小弟解释解释 这是什么情况? 拜托大佬解惑 谢谢
你这个程序运行结果并不能说明什么,应该线程分配完全是随机,你第2天运行该程序,或者换一台pc,运行的结果可能完全二样。
jack5246 2021-03-18
  • 打赏
  • 举报
回复
Thread.sleep 不会释放锁, sleep 之后线程会进入阻塞状态,继续持有锁
yue_hu 2021-03-18
  • 打赏
  • 举报
回复
sleep不会释放锁,如果你觉得多线程竞争不够直观的话可以减少线程数量,仅用两个线程,只有持有锁的才能运行,然后让一个线程sleep,查看另外一个线程是否会执行,就能得到结果了
HELLFS 2021-03-17
  • 打赏
  • 举报
回复
这样,我现在得出的结果就是正确的,但是我之前在b站复习时,看到在同步方法睡,可以实现多线程买票功能,哪位大佬可以解惑。 视频位置,B站狂神说的多线程 讲同步方法与同步块章节,同步方法案例
HELLFS 2021-03-17
  • 打赏
  • 举报
回复
引用 2 楼 叫练的回复:
Thread.sleep不释放锁,只有wait才释放锁,buy方法用到synchronized,而且是普通方法,所以这把锁是implementsRunnable 对象,sleep用到方法内,其他线程是获取不到锁的,用到方法外,说明,当前线程已经释放锁了,其他线程有进入获取monitor条件了。
implementRunnable对象是多线程公用的,那么同步方法中睡,不释放锁,则其他线程拿不到锁,无法执行下去,进入等待池,等待锁。其他线程不就堵塞了吗
老王就是我 2021-03-17
  • 打赏
  • 举报
回复
引用 2 楼 叫练 的回复:
Thread.sleep不释放锁,只有wait才释放锁,buy方法用到synchronized,而且是普通方法,所以这把锁是implementsRunnable 对象,sleep用到方法内,其他线程是获取不到锁的,用到方法外,说明,当前线程已经释放锁了,其他线程有进入获取monitor条件了。
sleep会把当前线程转为休眠中的状态,此时锁就没了。醒来后是重新和其它线程竞争锁。 wait()才是阻塞状态,其它线程未休眠的线程一样可以挑一个幸运儿进去执行方法
老王就是我 2021-03-17
  • 打赏
  • 举报
回复
sleep会释放锁,休眠时间之后会重新竞争锁
fai_jai 2021-03-16
  • 打赏
  • 举报
回复
说一下自己的看法,不一定对 1.在同步方法内sleep,sleep完之后应该是释放了锁,但之后立马又拿到了锁 2.在run方法中去掉睡眠,也是同一个线程拿到了锁,原因应该和上一点一样 3.状态打印并不准确 4.如果想要所有线程公平获取锁,起码要睡一段小的时间 thread.sleep方法的解释 使当前执行的线程在指定的毫秒数内休眠(临时停止执行),这取决于系统计时器和调度程序的精度和准确性。线程不会失去对任何监视器的所有权。
叫练 2021-03-16
  • 打赏
  • 举报
回复
Thread.sleep不释放锁,只有wait才释放锁,buy方法用到synchronized,而且是普通方法,所以这把锁是implementsRunnable 对象,sleep用到方法内,其他线程是获取不到锁的,用到方法外,说明,当前线程已经释放锁了,其他线程有进入获取monitor条件了。

62,620

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧