gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-11-30 06:44:52 26 4
gpt4 key购买 nike

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

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

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

我知道使用下面的代码我可以在另一个线程中执行 someObject.startit(),但每次都会从头开始创建,我无法承受线程创建的开销:

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

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

最佳答案

Is the main thread waiting for completion of someObject.startit() in the second thread(Being void as return type, I would think that this would not be the case)? Or is it executed in the first thread, therefore blocking it?

当您在multiTest 中直接调用someObject.startit() 时,它会在第一个调用线程中执行。

了解 Runnbale 不是 Thread 非常重要,Runnbale 只是普通对象,除了它的 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();
});

关于java - 从另一个线程调用方法时主线程被阻塞,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50024888/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com