Java 将线程的结果返回到单独的线程

Java 将线程的结果返回到单独的线程,java,multithreading,Java,Multithreading,例如,如果我有线程A和线程B。线程A是我的主线程,大多数应用程序都在这里运行,但当我需要从MySQL或其他外部源获取值时,我会创建一个新线程(线程B) 将值从线程B返回到线程A进行进一步处理而不导致线程A等待值可用的最佳方式是什么?使用队列,A将定期轮询队列,B可以异步将值放入队列使用队列,A将定期轮询队列,B可以异步地将值放入队列您可以使用ScheduledThreadPoolExecutor,它将返回Future,您不需要等待 示例用法(来自上的java文档) 接口ArchiveSearch

例如,如果我有线程A和线程B。线程A是我的主线程,大多数应用程序都在这里运行,但当我需要从MySQL或其他外部源获取值时,我会创建一个新线程(线程B)


将值从线程B返回到线程A进行进一步处理而不导致线程A等待值可用的最佳方式是什么?

使用队列,A将定期轮询队列,B可以异步将值放入队列使用队列,A将定期轮询队列,B可以异步地将值放入队列

您可以使用
ScheduledThreadPoolExecutor
,它将返回
Future
,您不需要等待

示例用法(来自上的java文档)

接口ArchiveSearcher{字符串搜索(字符串目标);}
类应用程序{
executor服务executor=。。。
ArchiveSearcher搜索器=。。。
void showSearch(最终字符串目标)
抛出中断异常{
未来
=执行者提交(新的可调用(){
公共字符串调用(){
返回搜索者。搜索(目标);
}});
displayOtherThings();//搜索时执行其他操作
试一试{
displayText(future.get());//使用future
}catch(ExecutionException ex){cleanup();return;}
}
}
将来的任务也可以实现同样的效果(访问上面的链接,示例仅来自那里)

FutureTask类是Future的一个实现,它实现了Runnable,因此可以由执行器执行。例如,上面带有submit的构造可以替换为:

 FutureTask<String> future =
       new FutureTask<String>(new Callable<String>() {
         public String call() {
           return searcher.search(target);
       }});
     executor.execute(future);
未来任务未来=
新建FutureTask(新的可调用(){
公共字符串调用(){
返回搜索者。搜索(目标);
}});
执行人。执行(未来);

您可以使用
ScheduledThreadPoolExecutor
,它将返回
Future
,您无需等待

示例用法(来自上的java文档)

接口ArchiveSearcher{字符串搜索(字符串目标);}
类应用程序{
executor服务executor=。。。
ArchiveSearcher搜索器=。。。
void showSearch(最终字符串目标)
抛出中断异常{
未来
=执行者提交(新的可调用(){
公共字符串调用(){
返回搜索者。搜索(目标);
}});
displayOtherThings();//搜索时执行其他操作
试一试{
displayText(future.get());//使用future
}catch(ExecutionException ex){cleanup();return;}
}
}
将来的任务也可以实现同样的效果(访问上面的链接,示例仅来自那里)

FutureTask类是Future的一个实现,它实现了Runnable,因此可以由执行器执行。例如,上面带有submit的构造可以替换为:

 FutureTask<String> future =
       new FutureTask<String>(new Callable<String>() {
         public String call() {
           return searcher.search(target);
       }});
     executor.execute(future);
未来任务未来=
新建FutureTask(新的可调用(){
公共字符串调用(){
返回搜索者。搜索(目标);
}});
执行人。执行(未来);

如果不想处理执行器,只需创建一个线程并将其传递给新线程即可

FutureTask<String> f = new FutureTask<String>(new Callable<String>() {
    @Override
    public String call() {
        return "";
    }
});
new Thread(f).start();
while (Thread.currentThread().isInterrupted()) {
    if (f.isDone()) {
        System.out.println(f.get());
        break;
    }
    //do smth else
}
FutureTask f=newfuturetask(newcallable()){
@凌驾
公共字符串调用(){
返回“”;
}
});
新线程(f.start();
而(Thread.currentThread().isInterrupted()){
if(f.isDone()){
System.out.println(f.get());
打破
}
//还有别的事吗
}

如果不想处理执行器,只需创建一个线程并将其传递给新线程即可

FutureTask<String> f = new FutureTask<String>(new Callable<String>() {
    @Override
    public String call() {
        return "";
    }
});
new Thread(f).start();
while (Thread.currentThread().isInterrupted()) {
    if (f.isDone()) {
        System.out.println(f.get());
        break;
    }
    //do smth else
}
FutureTask f=newfuturetask(newcallable()){
@凌驾
公共字符串调用(){
返回“”;
}
});
新线程(f.start();
而(Thread.currentThread().isInterrupted()){
if(f.isDone()){
System.out.println(f.get());
打破
}
//还有别的事吗
}

对于线程B,声明一个实现
Runnable
的类。例如:

public class MyClass implements Runnable
{
    private String input  = null;
    private String output = null;

    public MyClass(String input)
    {
        this.input = input;
    }

    public String getOutput()
    {
        return output;
    }

    public void run()
    {
        output = func(input);
    }
}
public String myFunc(String input) throws Exception
{
    MyClass object = new MyClass(input);
    Thread  thread = new Thread(object);

    thread.start();
    // Do whatever you wanna do...
    // ...
    // ...

    // And when you need the thread's output:
    thread.join();
    return object.getOutput();
}
在线程A(这是您的主线程)中,启动线程B,并等待它仅在您实际需要其输出的地方完成。例如:

public class MyClass implements Runnable
{
    private String input  = null;
    private String output = null;

    public MyClass(String input)
    {
        this.input = input;
    }

    public String getOutput()
    {
        return output;
    }

    public void run()
    {
        output = func(input);
    }
}
public String myFunc(String input) throws Exception
{
    MyClass object = new MyClass(input);
    Thread  thread = new Thread(object);

    thread.start();
    // Do whatever you wanna do...
    // ...
    // ...

    // And when you need the thread's output:
    thread.join();
    return object.getOutput();
}

对于线程B,声明一个实现
Runnable
的类。例如:

public class MyClass implements Runnable
{
    private String input  = null;
    private String output = null;

    public MyClass(String input)
    {
        this.input = input;
    }

    public String getOutput()
    {
        return output;
    }

    public void run()
    {
        output = func(input);
    }
}
public String myFunc(String input) throws Exception
{
    MyClass object = new MyClass(input);
    Thread  thread = new Thread(object);

    thread.start();
    // Do whatever you wanna do...
    // ...
    // ...

    // And when you need the thread's output:
    thread.join();
    return object.getOutput();
}
在线程A(这是您的主线程)中,启动线程B,并等待它仅在您实际需要其输出的地方完成。例如:

public class MyClass implements Runnable
{
    private String input  = null;
    private String output = null;

    public MyClass(String input)
    {
        this.input = input;
    }

    public String getOutput()
    {
        return output;
    }

    public void run()
    {
        output = func(input);
    }
}
public String myFunc(String input) throws Exception
{
    MyClass object = new MyClass(input);
    Thread  thread = new Thread(object);

    thread.start();
    // Do whatever you wanna do...
    // ...
    // ...

    // And when you need the thread's output:
    thread.join();
    return object.getOutput();
}

如果您有一个任务需要完成,您可以使用,并让另一个线程在方便的时候轮询(非阻塞)
isDone()
方法

如果该任务经常执行,或者您有许多任务要执行,那么使用a可能是一个更好的主意,它还提供了一个变体,支持阻塞,直到结果作为一个变量交付。再说一次:只要方便就在名单上投票就行了

如果不想轮询,可以使用回调功能。例如,如果使用Swing GUI,则可以从SwingUtilities类调用DB线程,因此在下一个可能的时间在主Swing线程上处理请求


这是基于类的,在某些其他场景中使用该类可能更方便。

如果需要完成单个任务,则可以使用,并让其他线程在方便时轮询(非阻塞)
isDone()
方法

如果该任务经常执行,或者您有许多任务要执行,那么使用a可能是一个更好的主意,它还提供了一个变体,支持阻塞,直到结果作为一个变量交付。再说一次:只要方便就在名单上投票就行了

如果不想轮询,可以使用回调功能。例如,如果使用Swing GUI,则可以从SwingUtilities类调用DB线程,因此在下一个可能的时间在主Swing线程上处理请求

这是基于类的,其中