Java多线程初学者指南(8):从线程返回数据的两种方法

简介:
  从线程中返回数据和向线程传递数据类似。也可以通过类成员以及回调函数来返回数据。但类成员在返回数据和传递数据时有一些区别,下面让我们来看看它们区别在哪。
一、 通过类变量和方法返回数据
使用这种方法返回数据需要在调用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 方法从线程中得到了三个随机数。因此,这种方法既可以向线程中传递数据,也可以从线程中获得数据。
 




 本文转自 androidguy 51CTO博客,原文链接:http://blog.51cto.com/androidguy/214829,如需转载请自行联系原作者

相关文章
|
6天前
|
运维 Java 程序员
Java中的异常处理方法
本文深入剖析Java异常处理机制,介绍可检查异常、运行时异常和错误的区别与处理方式。通过最佳实践方法,如使用合适的异常类型、声明精确异常、try-with-resources语句块、记录异常信息等,帮助开发者提高代码的可靠性、可读性和可维护性。良好的异常处理能保证程序稳定运行,避免资源泄漏和潜在问题。
|
6天前
|
传感器 监控 Java
Java代码结构解析:类、方法、主函数(1分钟解剖室)
### Java代码结构简介 掌握Java代码结构如同拥有程序世界的建筑蓝图,类、方法和主函数构成“黄金三角”。类是独立的容器,承载成员变量和方法;方法实现特定功能,参数控制输入环境;主函数是程序入口。常见错误包括类名与文件名不匹配、忘记static修饰符和花括号未闭合。通过实战案例学习电商系统、游戏角色控制和物联网设备监控,理解类的作用、方法类型和主函数任务,避免典型错误,逐步提升编程能力。 **脑图速记法**:类如太空站,方法即舱段;main是发射台,static不能换;文件名对仗,括号要成双;参数是坐标,void不返航。
26 5
|
25天前
|
存储 安全 算法
Java容器及其常用方法汇总
Java Collections框架提供了丰富的接口和实现类,用于管理和操作集合数据。
Java容器及其常用方法汇总
|
27天前
|
存储 缓存 Java
java语言后台管理ruoyi后台管理框架-登录提示“无效的会话,或者会话已过期,请重新登录。”-扩展知识数据库中密码加密的方法-问题如何解决-以及如何重置若依后台管理框架admin密码-优雅草卓伊凡
java语言后台管理ruoyi后台管理框架-登录提示“无效的会话,或者会话已过期,请重新登录。”-扩展知识数据库中密码加密的方法-问题如何解决-以及如何重置若依后台管理框架admin密码-优雅草卓伊凡
93 3
java语言后台管理ruoyi后台管理框架-登录提示“无效的会话,或者会话已过期,请重新登录。”-扩展知识数据库中密码加密的方法-问题如何解决-以及如何重置若依后台管理框架admin密码-优雅草卓伊凡
|
25天前
|
Python
python3多线程中使用线程睡眠
本文详细介绍了Python3多线程编程中使用线程睡眠的基本方法和应用场景。通过 `time.sleep()`函数,可以使线程暂停执行一段指定的时间,从而控制线程的执行节奏。通过实际示例演示了如何在多线程中使用线程睡眠来实现计数器和下载器功能。希望本文能帮助您更好地理解和应用Python多线程编程,提高程序的并发能力和执行效率。
53 20
|
25天前
|
Java API
java.time常用方法汇总
`java.time` API 是从 Java 8 开始引入的时间日期处理库,旨在替代老旧的 `java.util.Date` 和 `Calendar`。它提供了更简洁、强大和灵活的方式处理日期、时间、时区及时间间隔,支持全球化和时间计算需求。API 包含获取当前时间、创建指定时间、解析和格式化字符串、进行加减运算、比较时间、获取年月日时分秒、计算时间间隔、时区转换以及判断闰年等功能。示例代码展示了如何使用这些功能,极大简化了开发中的时间处理任务。
|
1月前
|
安全 Java C#
Unity多线程使用(线程池)
在C#中使用线程池需引用`System.Threading`。创建单个线程时,务必在Unity程序停止前关闭线程(如使用`Thread.Abort()`),否则可能导致崩溃。示例代码展示了如何创建和管理线程,确保在线程中执行任务并在主线程中处理结果。完整代码包括线程池队列、主线程检查及线程安全的操作队列管理,确保多线程操作的稳定性和安全性。
|
1月前
|
Linux
Linux编程: 在业务线程中注册和处理Linux信号
本文详细介绍了如何在Linux中通过在业务线程中注册和处理信号。我们讨论了信号的基本概念,并通过完整的代码示例展示了在业务线程中注册和处理信号的方法。通过正确地使用信号处理机制,可以提高程序的健壮性和响应能力。希望本文能帮助您更好地理解和应用Linux信号处理,提高开发效率和代码质量。
47 17
|
1月前
|
Linux
Linux编程: 在业务线程中注册和处理Linux信号
通过本文,您可以了解如何在业务线程中注册和处理Linux信号。正确处理信号可以提高程序的健壮性和稳定性。希望这些内容能帮助您更好地理解和应用Linux信号处理机制。
58 26
|
3月前
|
存储 安全 Java
Java多线程编程秘籍:各种方案一网打尽,不要错过!
Java 中实现多线程的方式主要有四种:继承 Thread 类、实现 Runnable 接口、实现 Callable 接口和使用线程池。每种方式各有优缺点,适用于不同的场景。继承 Thread 类最简单,实现 Runnable 接口更灵活,Callable 接口支持返回结果,线程池则便于管理和复用线程。实际应用中可根据需求选择合适的方式。此外,还介绍了多线程相关的常见面试问题及答案,涵盖线程概念、线程安全、线程池等知识点。
277 2

热门文章

最新文章