为什么主线程被阻塞?

huangapple go评论77阅读模式
英文:

Why main thread is blocked?

问题

我的要求是用户将持续在主线程中输入一些值而工作线程将获取这些值并在后台中运行而不会阻塞主线程并且当工作线程完成执行后它将返回值给主线程

我有以下的 Main.java 代码

private static ExecutorService service = Executors.newFixedThreadPool(3);

public static void main(String[] args) {
    try {
        Future<String> result = service.submit(new GerUserQuery());
        System.out.println("获取结果" + result.get());
        调用某些方法();
    } catch (InterruptedException | ExecutionException e) {
        e.printStackTrace();
    }
    service.shutdown();
}

以及 GerUserQuery.java 代码

public class GerUserQuery implements Callable<String> {

    @Override
    public String call() throws Exception {
        Thread.sleep(5000);
        执行IO操作();
        return "你好,世界";
    }
}

我想要做的是主线程将在这段代码之后继续执行而不会等待工作线程返回结果

Future<String> result = service.submit(new GerUserQuery());
System.out.println("获取结果" + result.get());

我遇到的问题是主线程总是在等待一旦工作线程返回结果然后调用 callSomeMethod()
我应该如何继续
英文:

My requirement is that, user will enter some values in the main thread continuously and the worker thread will take those values and run in background without blocking main thread and when worker thread is done with execution then it will return value to the main thread.

I have this following code Main.java

 private static ExecutorService service = Executors.newFixedThreadPool(3);

public static void main(String[] args) {
	try {
		    Future&lt;String&gt; result = service.submit(new GerUserQuery());
    	  	System.out.println(&quot;Get result&quot; + result.get());
    		callSomeMethod();
		} catch (InterruptedException | ExecutionException e) {
			e.printStackTrace();
		}
    	  	service.shutdown();

}

And the GerUserQuery.java

public class GerUserQuery implements Callable&lt;String&gt;{

@Override
public String call() throws Exception {
	Thread.sleep(5000);
    performIOOperation();
	return  &quot; hello world&quot; ;
  }
 }

What I am trying to do is that, the main thread will continue its execution after this line of codes without waiting for the worker thread to return the result.

  Future&lt;String&gt; result = service.submit(new GerUserQuery());
    	  	System.out.println(&quot;Get result&quot; + result.get()); 

The problem I have is that, the main thread is always waiting and once worker thread to return the result then callSomeMethod()is called.
How should I proceed?

答案1

得分: 2

这就是为什么它被阻塞:

System.out.println("获取结果" + result.get());

您正在使用阻塞主线程的get操作来请求结果。结果应该以异步方式返回,而不是使用get

移除日志以获得您想要的结果。

编辑:

要获取结果,您需要打开一个新线程,或者使用可以为您执行此操作的其他方法。

两者选一:

new Thread() {
    @Override
    public void run() {
        result.get(); // 这将给您结果。
    }
}.start();

我建议您研究一下Retrofit作为您的异步库,然后您可以像这样做:

Retrofit retrofit = new Retrofit.Builder()
    .baseUrl("https://api.github.com/")
    .build();

GitHubService service = retrofit.create(GitHubService.class);
service.listRepos().enqueue(new Callback<List<Repo>>() {
    @Override
    public void onResponse(Call<List<Repo>> call, Response<List<Repo>> response) {
        // 在这里处理您的结果
    }

    @Override
    public void onFailure(Call<List<Repo>> call, Throwable t) {
        // 处理请求失败的情况
    }
});

我没有完整填写方法声明,编译器和自动补全应该会帮助您完成。

英文:

This is why it is blocked:

            System.out.println(&quot;Get result&quot; + result.get());

You are asking for a result with a get operation that is blocking the main thread.
The result should return async, and not as "get"

Remove the log to get what you want

EDIT :

To get your result, you need to open a new thread, or you something that does it for you

Either :

new Thread() {
@Override
  public void run(){ 
      result.get(); //this will give you your result.
  }
 }.start();

I would suggest looking into Retrofit as your async lib, and then you could do something like this:

Retrofit retrofit = new Retrofit.Builder()
.baseUrl(&quot;https://api.github.com/&quot;)
.build();

 GitHubService service = 
  retrofit.create(GitHubService.class);
service.listRepos().enqueue({ 
     @Override
     public void onResponse () {
          //your result here
      }
 });

I didn't fill in the full method declarations, the compiler and auto complete should help you with that

huangapple
  • 本文由 发表于 2020年10月20日 00:59:51
  • 转载请务必保留本文链接:https://go.coder-hub.com/64431972.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定