当前位置: 首页 > 面试题库 >

从Java中的main()内部在线程实例上运行wait()

鱼安然
2023-03-14
问题内容

我正在使用java.lang.Object中的wait()的定时版本,并观察到它在两种不同的情况下的行为不同。

方案1:在线程中使用run()的默认定义

public static void main (String[] args) throws InterruptedException {
    Thread t = new Thread();    
    t.start();
    System.out.print("X");
    synchronized(t) { t.wait(10000);}
    System.out.print("Y");
}

方案1的问题:
我在X和Y之间遇到延迟。这是因为我正在从main调用wait()(即使在t上),因此正在使用主线程的调用堆栈,而不是主线程的调用堆栈。第二个线程?

方案2:动态 子类化Thread以重写run()以便打印内容。

public static void main (String[] args) throws InterruptedException {
     Thread t = new Thread() {public void run() 
                     {System.out.print("I am the second thread.");}};
     t.start();
     System.out.print("X");
     synchronized(t) { t.wait(10000);}
     System.out.print("Y");
}

关于方案2的问题: 我完全没有任何延迟!仅仅因为我重写了run(),发生了什么变化?现在,每次我运行程序时,它都会立即打印“
XI是第二个线程。Y”,而不会出现任何延迟!wait()的作用在哪里消失了?


问题答案:

该对螺纹精如何发送一个notifyAll的解释是相关的,正确的,从我+1。我将尝试添加一些有关为何如此重要的信息。

您打电话的时候

synchronized(t) { t.wait(10000);}

在主线程中,等待的是主线程。t是主线程正在等待的监视器。您对这应该使您的t线程处于休眠状态的预期是错误的。

此处的监视器(共享对象被锁定,恰好是t)被用于在不同线程之间进行通信,一个线程在监视器上调用notifyAll,而其他在监视器上等待的线程接收通知。您可以将监视器视为共享的通讯点。

在第一个示例中,线程t开始并立即结束(因为它没有任何关系)。在主线程开始等待之前,该线程完成并发送其通知,因此您会看到一个延迟,直到等待超时。

在第二个示例中,线程t需要打印一些内容,它与主线程之间存在竞争条件。这是万能的,首先发生的事情取决于计时的偶然性。您所看到的是线程t现在必须在控制台上打印一行,因此它设法保持足够长的忙碌时间,以便在主线程开始等待时它仍处于活动状态,从而允许主线程在以下情况下接收通知:
t完成,导致主线程缩短了等待时间。



 类似资料:
  • 我创建了两个类来计算数字,其中一个类同步执行,另一个类将其分成两半,并在两个线程中执行这两半。(intel i5(4个CPU),8GB ram)代码如下: 公共类: 多线程执行:public class Sheet2{

  • 我使用Apache中的HttpClient组件来执行以下简单的程序,并看到以下异常: 我正在使用 httpclient-4.3.3.jar httpcore-4.3.2.jar 有什么想法吗?

  • 问题内容: 这是一个普遍的Java问题,而不是Android的第一个问题! 我想从二级线程的上下文中了解如何在主线程上运行代码。例如: 这类事情-我意识到我的示例有点差,因为在Java中,您不需要进入主线程即可打印出某些内容,并且Swing也具有事件队列- 但在一般情况下,您可能需要在后台线程的上下文中,在主线程上运行Runnable。 编辑:为了进行比较-这是我在Objective-C中的做法:

  • 问题内容: 我正在用Java编写多线程应用程序,以提高顺序版本的性能。它是针对0/1背包问题的动态编程解决方案的并行版本。我有一个Intel Core 2 Duo,在不同的分区上都具有Ubuntu和Windows 7 Professional。我在Ubuntu中运行。 我的问题是并行版本实际上比顺序版本花费的时间更长。我认为这可能是因为所有线程都被映射到同一个内核线程,或者它们被分配给了同一个内核