Java Thread.sleep(),结合例子只学一次

x33g5p2x  于2022-02-18 转载在 Java  
字(2.7k)|赞(0)|评价(0)|浏览(329)

这个sleep的方法大家很常见也很常用,也别是刚开始玩代码的时候,很喜欢测试一些逻辑的时候,sleep一下。

sleep 有啥用: 

让线程在我们要它执行的时候执行,如果我们不要,那就让它睡,不占用 CPU 资源。

那么其实在使用多线程的时候,很容易关联到 锁的使用 ,synchronized 和 Lock这些 。

那么该篇文章其实核心内容是想让大家知道,sleep 与 锁资源之间的关系。

问题: 使用sleep时, 锁资源会释放吗?

示例介绍,一步一步来:

首先我们写下简单的测试代码:
 

  1. public class SleepTest implements Runnable {
  2. private int count = 1;
  3. @SneakyThrows
  4. @Override
  5. public void run() {
  6. while (true) {
  7. if (count < 10) {
  8. Thread.sleep(1000);
  9. }
  10. System.out.println(Thread.currentThread().getName() + "count=" + count);
  11. count++;
  12. if (count > 10) {
  13. break;
  14. }
  15. }
  16. }
  17. }

写个测试的调用代码:

  1. public static void main(String[] args) throws InterruptedException {
  2. SleepTest sleepTest=new SleepTest();
  3. Thread thread1=new Thread(sleepTest);
  4. Thread thread2=new Thread(sleepTest);
  5. thread1.start();
  6. thread2.start();
  7. }

运行效果:

上面这种是还没涉及到锁的情况,不存在锁资源竞争。那么接下来我们改下代码:
 

  1. @SneakyThrows
  2. @Override
  3. public void run() {
  4. while (true) {
  5. synchronized (this) {
  6. System.out.println("开始了" + Thread.currentThread().getName() + "count=" + count);
  7. if (count < 10) {
  8. Thread.sleep(1000);
  9. }
  10. System.out.println("睡醒了" + Thread.currentThread().getName() + "count=" + count);
  11. count++;
  12. if (count > 10) {
  13. break;
  14. }
  15. System.out.println("这时候执行完一轮,即将会释放锁" + Thread.currentThread().getName());
  16. }
  17. }
  18. }

注意了: 这时候我的 synchronized  加在的地方 注意了!

我是加在while里面的 , 大家看下执行效果:

 可以看到,红色是线程 0 ,蓝色是线程1 ,两个线程有交替输出现象。

不是说sleep不会释放锁资源吗?

其实认真看我的代码,我已经打出了一个输出在关键节点:

因为两个线程都进入到了while里面,   synchronized 框住的代码里面有sleep,这时候其实真的是不会释放锁资源的,所以看到
开始了Thread-1count=8
睡醒了Thread-1count=8
这时候执行完一轮,即将会释放锁Thread-1
这三阶段都是一段 一段 输出的 。

然后每一段输出完,锁自动释放。 那就是两个线程自由获取锁资源了。

紧接着,我们把synchronized 放在 while 外面 :

这时候的允许结果,无论执行多少次:

可以看到都是先拿到锁资源的线程,先进入自己的锁内代码块执行,就算里面sleep了,也不会释放锁资源,只有等到整个 synchronized 框住的代码块 执行完了,才释放锁资源 ; 然后另一个线程才拿的到锁,去执行相关代码块。

Sleep 不会释放 锁资源!

再继续搞多一个例子,也是更加明了: 

  1. private int count = 1;
  2. @SneakyThrows
  3. @Override
  4. public void run() {
  5. synctest();
  6. }
  7. private synchronized void synctest() throws InterruptedException {
  8. System.out.println(Thread.currentThread().getName()+"拿到锁!!!!!!!!!!");
  9. while (true) {
  10. System.out.println("开始了" + Thread.currentThread().getName() + "count=" + count);
  11. if (count < 10) {
  12. Thread.sleep(100);
  13. }
  14. System.out.println("睡醒了" + Thread.currentThread().getName() + "count=" + count);
  15. count++;
  16. if (count > 10) {
  17. System.out.println(Thread.currentThread().getName()+"大过10了,要出去了");
  18. break;
  19. }
  20. }
  21. System.out.println(Thread.currentThread().getName()+"while方法执行完了,把锁释放给别人");
  22. }
  23. }

看看这情况的执行效果 (大家可以自己想一下,看看与实际效果一不一样):
 

  1. public static void main(String[] args) throws InterruptedException {
  2. SleepTestNew sleepTest=new SleepTestNew();
  3. Thread thread1=new Thread(sleepTest);
  4. Thread thread2=new Thread(sleepTest);
  5. thread1.start();
  6. thread2.start();
  7. }

结果:

可以看到跟上一次效果一样,先拿到锁资源的线程0, 任意妄为,sleep 休息了很久,但是就是不把锁资源让出来, 别人 线程1 只能等到这个线程完全执行完了,才能拿到锁资源,但是此时count已经大于10了,拿到也没意思,只能根据逻辑出来了。

所以结论 :

Sleep 不会释放 锁资源!

Sleep 不会释放 锁资源!

Sleep 不会释放 锁资源!

ps: lock也是一样效果,就不在写代码举例了。

相关文章

最新文章

更多