当前位置: 首页 > 知识库问答 >
问题:

从另一个线程调用方法时主线程被阻塞

万高轩
2023-03-14

我试图用一个自定义对象创建一个新线程,然后从主线程调用这个自定义对象方法。其思想是,主线程可以继续执行其他任务,而自定义对象可以继续在第二个线程中工作:

public class Multithreading {
    public static void main(String[] args) {

        Multithreading mt = new Multithreading();
        mt.multiTest();
    }

    public void multiTest() {
        SomeObject someObject = new SomeObject();
        Thread thread = new Thread(someObject);
        thread.setDaemon(true);
        thread.start();
        someObject.startit();
        int i = 0;
        while (i < 3) { 
            try {

                System.out.println("this is the main thread being busy");

                Thread.sleep(3000);
                i += 1;
            } catch (InterruptedException e) {
            }

        }
    }

    class SomeObject implements Runnable {

        public void sayHello() {
            System.out.println("this is the second thread being busy");
        }

        public void startit() {
            int i = 0;
            while (i < 3) {
                try {
                    sayHello();

                    Thread.sleep(3000);
                    i += 1;
                } catch (InterruptedException e) {
                }
            }

        }

        @Override
        public void run() {
            // TODO Auto-generated method stub

        }
    }
}

输出为:

this is the second thread being busy
this is the second thread being busy
this is the second thread being busy
this is the main thread being busy
this is the main thread being busy
this is the main thread being busy

它应该更像这样:

this is the second thread being busy
this is the main thread being busy
this is the second thread being busy
this is the main thread being busy
this is the second thread being busy
this is the main thread being busy

所以主线程被阻塞,直到方法完成。主线程是否在第二个线程中等待的某个Object.startit()完成(作为返回类型为空,我认为情况不会如此)?还是在第一个线程中执行,因此阻塞了它?

我知道使用下面的代码,我可以在另一个线程中执行一些Object.startit(),但它每次都会从头开始创建,我负担不起线程创建开销:

new Thread(() -> {someObject.startit();}).start(); 

一个线程如何从另一个线程中的对象调用方法而不阻塞?

共有3个答案

席烨
2023-03-14

someObject。startit() 按顺序运行,而不是在您创建的线程上运行。

要使其工作,您需要调用startit() SomeObject的run()方法中的code>method

阎成天
2023-03-14

在另一个中执行的是可运行对象的run方法。在您的情况下,run方法是空的,因此在另一个线程中不会执行任何操作。然后从主线程调用startit(),因此它在主线程中执行。这就是为什么你会得到这个结果。

试着把startit()的主体放在run里面

澹台新知
2023-03-14

主线程是否在第二个线程中等待某个Object.startit()的完成(作为返回类型为false,我认为不会这样)?还是在第一个线程中执行,因此阻塞了它?

当你调用某个对象时。startit()直接在多测试中,它在第一个调用线程中执行。

重要的是要了解Runnbale不是ThreadRunnbale只是普通对象,除了它的run方法将在您使用它创建和启动一个新的Thread时执行,如下所示:

new Thread(new Runnable()).start;

所以,实际上,在这种情况下与线程阻塞无关。您可以将startit()移动到run方法,因此它将由第二个线程执行:

@Override
public void run() {
    startit();
}

而且,为了避免线程创建开销,您可以使用线程池来执行它:

ExecutorService executorService = Executors.newCachedThreadPool(); // It should a singlton
// ExecutorService executorService = Executors.newFixedThreadPool(threadSize);
executorService.execute(() -> {
    someObject.startit();
});
 类似资料:
  • 问题内容: 有没有简单的解决方案,可以在新线程中使用JPA将数据保存到数据库中? 我基于Spring的Web应用程序允许用户管理计划的任务。在运行时,他可以创建和启动预定义任务的新实例。我正在使用spring的TaskScheduler,并且一切正常。 但是我需要将每个被激发任务的布尔结果保存到数据库中。我怎样才能做到这一点? 编辑:我必须概括我的问题:我需要从任务在我的@Service类上调用方

  • 我如何启动两个线程,其中thread1首先执行,thread2在thread1结束时启动,而主方法线程可以在不锁定其他两个线程的情况下继续工作? 我尝试了join(),但是它需要从线程调用,线程必须等待另一个线程,没有办法执行类似thread2.join(thread1)的操作;因此,如果我在main()中调用join,我将有效地停止主线程的执行,而不仅仅是Thread2的执行。 #编辑:为什么我

  • 目前,我使用的是firebase实时数据库。因此,我的数据更改来自另一个线程。因此,我无法控制何时更新新的数据。然后我如何知道何时调用以刷新UI? 谢谢

  • 在一个android服务中,我创建了用于执行一些后台任务的线程。 我遇到一个情况,线程需要在主线程的消息队列上发布特定任务,例如。 有没有方法获取主线程的并从我的另一个线程向它发布/?

  • 以下是问题陈述: 编写一个java程序,使用线程计算前25个素数,并计算前50个斐波那契数。将计算斐波那契数的线程的优先级设置为8,将另一个设置为5。在计算了30个斐波那契数之后,让这个线程进入睡眠状态,开始计算素数。计算完25个素数后,继续斐波那契数计算。 我的代码: 我本以为当斐波那契线停止时,其余的素数会被打印出来,但那没有发生,这背后的原因可能是什么?

  • 问题内容: 如何在Android中从辅助线程调用主线程? 问题答案: 最简单的方法是从线程中调用runOnUiThread(…)