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

为什么在Java中的线程对象上调用start()时没有立即调用run()

淳于健
2023-03-14
问题内容

还是?
我有一个来自的线程对象:

Thread myThread = new Thread(pObject);

其中pObject是实现Runnable接口的类的对象,然后在线程对象上调用start方法,如下所示:

myThread.start();

现在,我的理解是,当调用start()时,JVM隐式(立即)调用了run()方法,该方法可能会被覆盖(就我而言)

但是,在我的情况下,似乎没有立即(根据需要)调用start()方法,而是直到从调用块完成其他语句/方法为止,即,如果在start()调用之后我有一个方法,例如:

myThread.start();
doSomethingElse();

在运行run()方法之前,先执行doSomthingElse()。
最初的前提是始终在调用start()之后立即调用run()可能使我错了。请帮忙!再次希望在start()之后立即执行run()。谢谢。


问题答案:

现在,我的理解是,当调用start()时,JVM隐式(立即)调用了run()方法。

那是不对的。它确实隐式调用run(),但是调用不一定立即发生。

现实情况是,在进行start()调用之后的某个时间点,可以安排新线程使用。实际调度取决于本机调度程序。它可能会立即发生,或者父线程可能会在安排子线程之前持续一段时间。

为了强制您的线程立即开始运行(或者更准确地说,是在之前开始运行doSomethingElse()),您需要执行一些显式同步;例如这样的事情:

    java.util.concurrent.CountDownLatch latch = new CountdownLatch(1);
    new Thread(new MyRunnable(latch)).start();
    latch.await(); // waits until released by the child thread.
    doSomethingElse();

哪里

class MyRunnable implements Runnable {
    private CountDownLatch latch;
    MyRunnable (CountDownLatch latch) { this.latch = latch; }
    public void run() {
        doSomeStuff();
        latch.countDown(); // releases the parent thread
        doSomeMoreStuff();
    }
    ...
}

还有其他方法可以使用并发类或Java的互斥/等待/通知原语1实现同步。但是,两个线程之间的显式同步是保证所需行为的唯一方法。

请注意,doSomething()子线程中的调用将在释放父线程之前完成,但是我们不能说doSomethingElese()和的执行顺序doSomeMoreStuff()。(一个可以在另一个之前运行,反之亦然,或者它们可以并行运行。)

1- 不建议使用wait/ notify,但是如果并发API不可用,它可能是您唯一的选择;例如在Java ME上。



 类似资料:
  • 问题内容: 在我的情况2中,当我尝试从文件csvv.txt中取回名称时,该文件不起作用,因为该文件实际上没有数据。但是当我单独运行案例1时,数据在文件中写入 问题答案: 不会立即写入,因为它会 缓冲 给定的数据。 假设您在公司的邮件室工作。有人走进来并寄给客户。您需要10分钟才能到街上的邮局邮寄。您会立即接受这封信,还是会等着看是否有人会先给您带来一封信? 这是缓冲:您不必等待立即进行繁琐的操作(

  • 我需要使一个库,我将有同步和异步的特点。 -等待得到结果,返回结果。 -立即返回一个将来值,如果需要,该将来值可以在其他事情完成后处理。 my Library的核心逻辑 将执行实际任务的简单类: 当我开始处理此解决方案时,我并没有终止超时的任务。我向客户机报告超时,但任务继续在线程池中运行(可能会长时间占用我有限的10个线程中的一个)。所以我在网上做了一些研究,我发现我可以通过使用取消未来来取消超

  • 问题内容: 这可能是一个基本问题,我对此感到困惑, 在一个文件中,我是这样的: 现在在另一个文件中我有这个: 所以在上面两种情况之间有什么区别,情况1是否正在创建新线程,情况2是否未创建线程?那是我的猜测…希望大家能更好地回答。谢谢 问题答案: 在新线程中运行代码。直接调用不会在新线程中执行,而是从中调用该线程。 如果直接调用,则没有线程。直接调用将阻塞,直到完成任何代码。 创建一个新线程,并且由

  • 我创建了一个可运行的类a,它为我执行一些任务。我使用ExecutorService提交这个类,以便并行执行这些任务。 可运行类A调用另一个对象B,该对象发送一个AsyncFuture请求(future.get()one)。 我将可运行类A的单独对象提交给ExecutorService,但是,类B的对象由bean(单例)引用。这会导致线程执行出现问题吗? 我注意到类A的一些对象没有被任何线程执行。

  • 在上面的代码中,我得到的输出是: 在我做 d1.name 之后=“亚瑟” 我期望输出是

  • 来自JDBC规范 关闭语句对象将关闭该语句对象生成的任何ResultSet实例并使其无效。在垃圾收集再次运行之前,ResultSet对象持有的资源可能不会被释放,因此当不再需要ResultSet对象时,显式关闭它们是一种很好的做法。 > 调用ResultSet.close()是否立即释放ResultSet对象? 调用Statement.close()是否立即释放语句对象? 调用语句。close()