`
chen291382932
  • 浏览: 6794 次
  • 性别: Icon_minigender_1
  • 来自: 郑州
社区版块
存档分类
最新评论

从线程返回数据的两种方法

 
阅读更多

从线程中返回数据和向线程传递数据类似。也可以通过类成员以及回调函数来返回数据。但类成员在返回数据和传递数据时有一些区别,下面让我们来看看它们区别在哪。

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

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

  1. package mythread;  
  2.  
  3. public class MyThread extends Thread  
  4. {  
  5.     private String value1;  
  6.     private String value2;  
  7.  
  8.     public void run()  
  9.     {  
  10.         value1 = "通过成员变量返回数据";  
  11.         value2 = "通过成员方法返回数据";  
  12.     }  
  13.     public static void main(String[] args) throws Exception  
  14.     {  
  15.         MyThread thread = new MyThread();  
  16.         thread.start();  
  17.         System.out.println("value1:" + thread.value1);  
  18.         System.out.println("value2:" + thread.value2);  
  19.     }  
  20. }  

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

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时,就可以输出这两个值了。我们可以使用如下的代码来达到这个目的:

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

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

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

在while循环中第判断一次value1和value2的值后休眠100毫秒,然后再判断这两个值。这样所占用的系统资源会小一些。

上面的方法虽然可以很好地解决,但Java的线程模型为我们提供了更好的解决方案,这就是join方法。在前面已经讨论过,join的功能就是使用线程从异步执行变成同步执行。当线程变成同步执行后,就和从普通的方法中得到返回数据没有什么区别了。因此,可以使用如下的代码更有效地解决这个问题:

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

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

二、通过回调函数返回数据

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

分享到:
评论

相关推荐

    易语言线程返回数据的方法源码

    本文将深入探讨如何在易语言中实现线程返回数据的方法,以及相关的源码解析。 易语言是一种面向对象、中文编程的计算机程序设计语言,其目标是使普通用户也能方便地进行软件开发。在易语言中,我们可以使用“创建...

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

    Java多线程编程中,从线程返回数据是并发编程中的常见需求,通常有以下两种主要方法:通过类成员变量和方法返回数据,以及通过回调函数返回数据。 ### 一、通过类成员变量和方法返回数据 这种方法的核心是利用线程...

    Java多线程初学者指南(7):向线程传递数据的三种方法.docx )

    上面讨论的两种向线程中传递数据的方法都是 main 方法中主动将数据传入线程类的。这对于线程来说,是被动接收这些数据的。然而,在有些应用中需要在线程运行的过程中动态地获取数据。例如,以下代码演示了如何使用回...

    Qt两种方法实现多线程并安全结束线程及QMutex加锁Qt单例化实现

    - **线程同步**:QMutex是一种互斥锁,用于保护共享资源不被多个线程同时访问。在访问关键区域(可能引发竞争条件的部分)之前,应调用`lock()`,访问结束后调用`unlock()`。 - **加锁技巧**:确保每次`unlock()`...

    java中创建线程两个方法及区别

    Java提供了多种创建线程的方式,其中最常见的是通过继承`Thread`类和实现`Runnable`接口这两种方法。下面将详细阐述这两种创建线程的方法及其区别。 ### 一、通过继承`Thread`类创建线程 当一个类继承了`Thread`类...

    数据流和多线程笔记

    - **创建线程**:Java中有两种常见的创建线程的方式: - 继承`Thread`类并重写`run()`方法。 - 实现`Runnable`接口,编写`run()`方法,然后将其传递给`Thread`对象。 - **线程同步**:当多个线程访问共享资源时,...

    C#TCP协议服务器客户端通信源码(服务器多线程处理数据)

    首先,TCP(Transmission Control Protocol)是一种面向连接的、可靠的传输协议,它通过三次握手建立连接,并在数据传输过程中通过确认和重传机制确保数据的正确性。在C#中,`System.Net.Sockets`命名空间下的`Tcp...

    多线程技术在数据实时采集分析中的应用.doc

    由于数据量大且需要实时分析,数据采集和分析被分配到两个独立的线程中。主界面线程管理用户交互,而数据采集线程和数据分析线程协同工作,确保数据的连续性和完整性。 为了实现高效的数据流处理,系统使用了高速...

    QT多线程moveToThread使用方式

    可以使用`quit()`方法来停止事件循环,然后等待`wait()`方法返回,确保线程已退出。 在提供的`TestMoveToThread`文件中,可能包含了具体的示例代码,演示了如何创建和使用`moveToThread`方法。这个例子可能包括两个...

    子线程中更新UI线程的三种方法

    以下将详细讲解三种在子线程中更新UI线程的方法,特别是Handler的两种用法。 1. Handler+Looper Handler是Android中用于消息传递的关键组件,它与Looper配合使用,可以在不同线程之间传递消息。首先,我们需要在...

    C#多线程互斥实例 多线程获取同一变量

    测试这个多线程互斥的例子,我们可以创建多个线程,每个线程分别调用`Increment`或`Decrement`方法,然后观察`GetValue`返回的值是否正确反映了操作的顺序。在`多线程test`这个项目中,很可能包含了这样的测试代码,...

    线程方法操作

    在Java中,可以通过以下两种方式创建线程: - 继承`Thread`类:自定义一个类继承`Thread`,重写`run()`方法,然后实例化并调用`start()`方法启动线程。 - 实现`Runnable`接口:创建一个实现了`Runnable`接口的类...

    C#多线程处理实例

    Thread 类的构造方法主要有两种: 1. Thread thread_name=Thread(ThreadStart):ThreadStart 委托,它表示此线程开始执行时要调用的方法。适用于无参数的方法。 2. Thread thread_name=Thread...

    线程间通信方式3:消息传递方式

    消息传递可以作为避免数据竞争的一种手段,因为每个线程通过消息队列顺序地接收和处理消息,而不是直接访问共享数据。 - 但需要注意的是,如果消息涉及到共享资源,仍需使用互斥量或临界区来保护这些资源。 6. **...

    Java线程从入门到实践

    6. 从线程返回数据: 线程返回数据可以使用`Callable`接口,它允许返回一个结果,配合`Future`接口获取结果。另外,还可以通过共享数据结构或回调函数来实现。 7. `synchronized`关键字: `synchronized`用于实现...

    多线程编程之三——线程间通讯

    在某些编程语言(如Go)中,通道是一种内建的线程间通信机制,允许数据在两个线程间安全地传递。 7. 使用队列(Queue) 线程间可以共享一个队列,一个线程生产数据,另一个线程消费数据。这种方法需要配合同步原语...

    java多线程应用实现方法

    Java多线程应用实现主要涉及两种方式:继承Thread类和实现Runnable接口。这两种方法都是为了在Java程序中创建并管理多个并发执行的任务,从而提高程序的执行效率。 1. 继承Thread类: 当一个类直接继承Thread类时,...

    Java 多线程 PPT

    创建Java线程主要有两种方式: 1. 继承Thread类:创建Thread的子类并重写run()方法,然后通过调用start()方法启动线程。 2. 实现Runnable接口:创建一个实现了Runnable接口的类,实现run()方法,然后将该类的实例...

    Posix线程编程指南

    线程与进程是操作系统中两种不同的执行流。进程是资源管理的基本单位,而线程则是执行的基本单位。线程在进程内部创建,共享进程的资源,如文件描述符、内存空间等,但拥有自己的执行栈和程序计数器。多线程编程可以...

Global site tag (gtag.js) - Google Analytics