前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >juc06-BLOCKED状态

juc06-BLOCKED状态

作者头像
潇洒
发布2023-10-20 10:11:06
920
发布2023-10-20 10:11:06
举报
文章被收录于专栏:石头岛

前言

java线程模型中有5种线程状态。五种状态之间可以进行转换。

强调一下 BLOCKED 状态跟 I/O 的阻塞是不同的,它不是一般意义上的阻塞,而是特指被 synchronized 块阻塞,即是跟线程同步有关的一个状态。

BLOCKED(阻塞)

简单定义为:

A thread that is blocked waiting for a monitor lock is in this state. 一个正在阻塞等待一个监视器锁的线程处于这一状态。

两种阻塞的情况:

第一种:

A thread in the blocked state is waiting for a monitor lock to enter a synchronized block/method. 一个处于 blocked 状态的线程正在等待一个监视器锁以进入一个同步的块或方法。

第二种:

A thread in the blocked state is waiting for a monitor lock to reenter a synchronized block/method after calling Object.wait。 一个处于 blocked 状态的线程正在等待一个监视器锁,在其调用 Object.wait 方法之后,以再次进入一个同步的块或方法。

进入(enter)同步块时阻塞

监视器锁用于同步访问,以达到多线程间的互斥。所以一旦一个线程获取锁进入同步块,在其出来之前,如果其它线程想进入,就会因为获取不到锁而阻塞在同步块之外,这时的状态就是 BLOCKED。 注:这一状态的进入及解除都不受我们控制,当锁可用时,线程即从阻塞状态中恢复。

wait 之后重进入(reenter)同步块时阻塞

举个场景:

  1. 调用 wait 方法必须在同步块中,即是要先获取锁并进入同步块,这是第一次 enter。 而调用 wait 之后则会释放该锁,并进入此锁的等待队列(wait set)中。
  2. 当收到其它线程的 notify 或 notifyAll 通知之后,等待线程并不能立即恢复执行,因为停止的地方是在同步块内,而锁已经释放了,所以它要重新获取锁才能再次进入(reenter)同步块,然后从上次 wait 的地方恢复执行。

这是第二次 enter,所以叫 reenter。 但锁并不会优先给它,该线程还是要与其它线程去竞争锁,这一过程跟 enter 的过程其实是一样的,因此也可能因为锁已经被其它线程据有而导致 BLOCKED。

模拟 BLOCKED 代码

代码语言:javascript
复制
@Test
public void testBlocked() throws Exception {
    class Counter {
        int counter;
        public synchronized void increase() {
            counter++;
            try {
                Thread.sleep(30000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
    }

    Counter c = new Counter();

    Thread t1 = new Thread(new Runnable() {
        public void run() {
            c.increase();
        }
    }, "t1线程");
    t1.start();

    Thread t2 = new Thread(new Runnable() {
        public void run() {
            c.increase();
        }
    }, "t2线程");
    t2.start();

    Thread.sleep(100); // 确保 t2 run已经得到执行
    assertThat(t2.getState()).isEqualTo(Thread.State.BLOCKED);
}

总结

为什么专门提这一块,因为后面在排查问题,查看错误的vm_log时,线常会看到BLOCKED状态,需要了解这个状态代表什么,排查问题才看的问是什么意思。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2014-10-22,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • BLOCKED(阻塞)
  • 进入(enter)同步块时阻塞
  • wait 之后重进入(reenter)同步块时阻塞
  • 模拟 BLOCKED 代码
  • 总结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档