Java线程wait() => 阻塞?

12 浏览
0 Comments

Java线程wait() => 阻塞?

根据Java线程状态信息,调用wait()方法会导致线程进入BLOCKED状态。然而,这段代码在被调用后会导致线程进入WAITING状态。我是否理解错了?有人可以解释一下这种行为吗?谢谢!

0
0 Comments

Java中的线程有几种状态,其中之一是WAITING状态。在Java中,当一个线程调用Object.wait()方法时,它会进入WAITING状态。另一种状态是BLOCKED状态,当线程在调用synchronized块或方法之前被阻塞时,它会进入BLOCKED状态。

有人可能会混淆WAITING状态和BLOCKED状态之间的区别。在Java文档中,明确说明了WAITING状态是在调用Object.wait()方法之后发生的,而BLOCKED状态是在进入synchronized块或方法之前发生的。

混淆的原因可能是因为文档中提到了"reenter a synchronized block",即在调用Object.wait()方法之后重新进入synchronized块。这可能导致一些人错误地认为WAITING状态是在BLOCKED状态之后发生的。

解决这个问题的方法是正确理解两个状态之间的区别。WAITING状态是在调用Object.wait()方法之后发生的,而BLOCKED状态是在进入synchronized块或方法之前发生的。

下面是一个示例代码,演示了线程在WAITING状态和BLOCKED状态之间的转换:

public class ThreadExample {
   public static void main(String[] args) {
      final Object lock = new Object();
      Thread thread1 = new Thread(new Runnable() {
         public void run() {
            synchronized(lock) {
               try {
                  lock.wait(); // 线程进入WAITING状态
               } catch (InterruptedException e) {
                  e.printStackTrace();
               }
            }
         }
      });
      Thread thread2 = new Thread(new Runnable() {
         public void run() {
            synchronized(lock) {
               // 执行一些操作
            }
         }
      });
      thread1.start(); // 启动线程1
      thread2.start(); // 启动线程2
   }
}

在上面的示例中,线程1在调用lock.wait()方法后进入WAITING状态,而线程2在进入synchronized块之前进入BLOCKED状态。这个例子清楚地展示了两个状态之间的转换。

总结起来,Java中的线程在调用Object.wait()方法后进入WAITING状态,而在进入synchronized块或方法之前进入BLOCKED状态。正确理解这两个状态的区别对于编写多线程应用程序非常重要。

0
0 Comments

Java中的线程在调用wait()方法时会进入WAITING状态,直到被notify()或者notifyAll()方法唤醒。然后它会尝试重新进入同步区域,此时进入BLOCKED状态,直到其他所有线程离开该区域。

关于WAITING状态的部分内容如下:

例如,一个线程调用了一个对象的Object.wait()方法,它会等待另一个线程调用该对象的Object.notify()或者Object.notifyAll()方法。

关于BLOCKED状态的部分内容如下:

处于BLOCKED状态的线程正在等待获取监视器锁,以便在调用Object.wait()后重新进入同步块/方法。

最后一部分内容表示线程在调用wait()方法后尝试返回,但在此之前不会执行任何操作。

这是否意味着被阻塞的线程在获取锁的过程中循环执行?换句话说,被阻塞的线程会消耗CPU时间吗?

答案是否定的。线程会在保护同步区域的互斥体的就绪队列中,就像调用被另一个线程锁定的同步函数一样。在锁争用方面需要关注的主要开销通常是它会导致程序上下文切换(即在CPU中存储和恢复运行线程的状态),这是相对昂贵的。

因此,可以得出以下结论:

- 线程在调用wait()方法后进入WAITING状态,直到被唤醒;

- 被唤醒后,线程尝试重新进入同步区域,此时进入BLOCKED状态;

- 被阻塞的线程不会循环获取锁,它只是等待在就绪队列中;

- 锁争用会导致程序上下文切换,这是需要关注的性能开销。

解决方法:需要根据具体情况来决定是否需要使用wait()和notify()方法,并且需要注意避免过多的锁争用,以减少程序上下文切换的开销。

0
0 Comments

Java中的线程等待(Thread wait())会导致线程被阻塞的原因是,当一个线程需要等待另一个线程提供某些信息时,它会调用wait()方法将自己标记为WAITING状态,直到被notify()方法唤醒。在这种情况下,等待的线程将不会被监视器执行,直到被唤醒为止。换句话说,WAITING状态的线程不能直接从WAITING变为RUNNABLE状态,而是需要先进入BLOCKED状态。

解决方法可以是在等待的线程中使用notify()方法,当满足某个条件时唤醒等待的线程,使其进入BLOCKED状态,然后再由监视器选择一个新的线程来执行。这样,原本处于WAITING状态的线程就有机会被执行了。

总结一下,Java中的线程等待状态(WAITING)和阻塞状态(BLOCKED)都是线程的非活动状态,但是WAITING状态的线程在变为RUNNABLE状态之前必须先进入BLOCKED状态。WAITING状态的线程不主动变为活动状态,而BLOCKED状态的线程希望变为活动状态,但由于还没有轮到它们执行,所以无法变为活动状态。

以上是对问题"Java Thread wait() => blocked?"出现的原因以及解决方法的整理。

0