java多线程编程之从线程返回数据的两种方法

 更新时间:2014年01月23日 14:55:07   作者:  
从线程中返回数据和向线程传递数据类似。也可以通过类成员以及回调函数来返回数据。但类成员在返回数据和传递数据时有一些区别,下面让我们来看看它们区别在哪

一、通过类变量和方法返回数据

使用这种方法返回数据需要在调用start方法后才能通过类变量或方法得到数据。让我们先来看看例程2-13会得到什么结果。

复制代码 代码如下:

package mythread;

public class MyThread extends Thread
{
    private String value1;
    private String value2;

    public void run()
    {
        value1 = "通过成员变量返回数据";
        value2 = "通过成员方法返回数据";
    }
    public static void main(String[] args) throws Exception
    {
        MyThread thread = new MyThread();
        thread.start();
        System.out.println("value1:" + thread.value1);
        System.out.println("value2:" + thread.value2);
    }
}



运行上面的代码有可能输出如下的结果:
复制代码 代码如下:

value1:null
value2:null

从上面的运行结果看很不正常。在run方法中已经对value1和value2赋了值,而返回的却是null。发生这种情况的原因是调用start方法后就立刻输出了value1和value2的值,而这里run方法还没有执行到为value1和value2赋值的语句。要避免这种情况的发生,就需要等run方法执行完后才执行输出value1和value2的代码。因此,我们可以想到使用sleep方法将主线程进行延迟,如可以在thread.start()后加一行如下的语句:
sleep(1000);
这样做可以使主线程延迟1秒后再往下执行,但这样做有一个问题,就是我们怎么知道要延迟多长时间。在这个例子的run方法中只有两条赋值语句,而且只创建了一个线程,因此,延迟1秒已经足够,但如果run方法中的语句很复杂,这个时间就很难预测,因此,这种方法并不稳定。
我们的目的就是得到value1和value2的值,因此,只要判断value1和value2是否为null。如果它们都不为null时,就可以输出这两个值了。我们可以使用如下的代码来达到这个目的:

复制代码 代码如下:

while (thread.value1 == null || thread.value2 == null);

使用上面的语句可以很稳定地避免这种情况发生,但这种方法太耗费系统资源。大家可以设想,如果run方法中的代码很复杂,value1和value2需要很长时间才能被赋值,这样while循环就必须一直执行下去,直到value1和value2都不为空为止。因此,我们可以对上面的语句做如下的改进:

复制代码 代码如下:

while (thread.value1 == null || thread.value2 == null)
    sleep(100);

在while循环中第判断一次value1和value2的值后休眠100毫秒,然后再判断这两个值。这样所占用的系统资源会小一些。
上面的方法虽然可以很好地解决,但Java的线程模型为我们提供了更好的解决方案,这就是join方法。在前面已经讨论过,join的功能就是使用线程从异步执行变成同步执行。当线程变成同步执行后,就和从普通的方法中得到返回数据没有什么区别了。因此,可以使用如下的代码更有效地解决这个问题:

复制代码 代码如下:

thread.start();
thread.join();

在thread.join()执行完后,线程thread的run方法已经退出了,也就是说线程thread已经结束了。因此,在thread.join()后面可以放心大胆地使用MyThread类的任何资源来得到返回数据。

二、通过回调函数返回数据
其实这种方法已经在《向线程传递数据的三种方法》中介绍了。在《向线程传递数据的三种方法》一文的例子中通过Work类的process方法向线程中传递了计算结果,但同时,也通过process方法从线程中得到了三个随机数。因此,这种方法既可以向线程中传递数据,也可以从线程中获得数据。

相关文章

  • EasyExcel实现读写Excel文件的示例代码

    EasyExcel实现读写Excel文件的示例代码

    EasyExcel是阿里巴巴开源的一个excel处理框架,以使用简单、节省内存著称。它可以在尽可能节约内存的情况下支持读写百M的Excel,所以本文就将利用它实现读写Excel文件,感兴趣的可以了解一下
    2022-08-08
  • Spring Validator接口校验与全局异常处理器

    Spring Validator接口校验与全局异常处理器

    这篇文章主要介绍了Spring Validator接口校验与全局异常处理器,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-11-11
  • java发起http请求获取返回的Json对象方法

    java发起http请求获取返回的Json对象方法

    下面小编就为大家分享一篇java发起http请求获取返回的Json对象方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-03-03
  • java class name实例深入精讲

    java class name实例深入精讲

    这篇文章主要为大家介绍了java class name实例深入精讲,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-09-09
  • 一篇文章带你了解XGBoost算法

    一篇文章带你了解XGBoost算法

    XGBoost全名叫(eXtreme Gradient Boosting)极端梯度提升,经常被用在一些比赛中,其效果显著。它是大规模并行boosted tree的工具,它是目前最快最好的开源boosted tree工具包
    2021-08-08
  • Java多线程之读写锁分离设计模式

    Java多线程之读写锁分离设计模式

    这篇文章主要介绍了Java多线程读写锁分离设计模式,主要利用Java到吗完成read read 并行化、read write 不允许、write write 不允许几项任务,需要的朋友可以参考一下
    2021-10-10
  • Java String类简单用法实战示例【字符串输出、比较】

    Java String类简单用法实战示例【字符串输出、比较】

    这篇文章主要介绍了Java String类简单用法,结合具体实例形式分析了Java使用String类实现字符串的输出和比较功能相关操作技巧,需要的朋友可以参考下
    2019-07-07
  • Redisson分布式锁源码解析

    Redisson分布式锁源码解析

    文章给大家分享了关于Redisson分布式锁源码相关的知识点内容,有兴趣的朋友们可以参考学习下。
    2018-08-08
  • 浅析 ArrayList 和 LinkedList 有什么区别

    浅析 ArrayList 和 LinkedList 有什么区别

    ArrayList 和 LinkedList 有什么区别,是面试官非常喜欢问的一个问题。今天通过本文给大家详细介绍下,感兴趣的朋友跟随小编一起看看吧
    2020-10-10
  • SpringBoot2.0集成MQTT消息推送功能实现

    SpringBoot2.0集成MQTT消息推送功能实现

    这篇文章主要介绍了SpringBoot2.0集成MQTT消息推送功能实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-04-04

最新评论