`
palwang
  • 浏览: 51377 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
文章分类
社区版块
存档分类
最新评论

Java向线程传递数据的三种方法

阅读更多
在传统的同步开发模式下,当我们调用一个函数时,通过这个函数的参数将数据传入,并通过这个函数的返回值来返回最终的计算结果。但在多线程的异步开发模式下,数据的传递和返回和同步开发模式有很大的区别。由于线程的运行和结束是不可预料的,因此,在传递和返回数据时就无法象函数一样通过函数参数和 return语句来返回数据。本文就以上原因介绍了几种用于向线程传递数据的方法,在下一篇文章中将介绍从线程中返回数据的方法。

  欲先取之,必先予之。一般在使用线程时都需要有一些初始化数据,然后线程利用这些数据进行加工处理,并返回结果。在这个过程中最先要做的就是向线程中传递数据。

  一、通过构造方法传递数据

  在创建线程时,必须要建立一个Thread类的或其子类的实例。因此,我们不难想到在调用start方法之前通过线程类的构造方法将数据传入线程。并将传入的数据使用类变量保存起来,以便线程使用(其实就是在run方法中使用)。下面的代码演示了如何通过构造方法来传递数据:

   package mythread;
    
   public class MyThread1 extends Thread {
       private String name;
   
       public MyThread1(String name) {
           this.name = name;
       }
   
       public void run() {
           System.out.println("hello " + name);
       }
   
       public static void main(String[] args) {
           Thread thread = new MyThread1("world");
           thread.start();
       }
   }

  由于这种方法是在创建线程对象的同时传递数据的,因此,在线程运行之前这些数据就就已经到位了,这样就不会造成数据在线程运行后才传入的现象。如果要传递更复杂的数据,可以使用集合、类等数据结构。使用构造方法来传递数据虽然比较安全,但如果要传递的数据比较多时,就会造成很多不便。由于 Java没有默认参数,要想实现类似默认参数的效果,就得使用重载,这样不但使构造方法本身过于复杂,又会使构造方法在数量上大增。因此,要想避免这种情况,就得通过类方法或类变量来传递数据。

  二、通过变量和方法传递数据

  向对象中传入数据一般有两次机会,第一次机会是在建立对象时通过构造方法将数据传入,另外一次机会就是在类中定义一系列的public的方法或变量(也可称之为字段)。然后在建立完对象后,通过对象实例逐个赋值。下面的代码是对MyThread1类的改版,使用了一个setName方法来设置 name变量:

   package mythread;
   
   public class MyThread2 implements Runnable {
       private String name;
   
       public void setName(String name) {
           this.name = name;
       }
   
       public void run() {
           System.out.println("hello " + name);
       }
   
       public static void main(String[] args) {
           MyThread2 myThread = new MyThread2();
           myThread.setName("world");
           Thread thread = new Thread(myThread);
           thread.start();
       }
   }

   三、通过回调函数传递数据

  上面讨论的两种向线程中传递数据的方法是最常用的。但这两种方法都是main方法中主动将数据传入线程类的。这对于线程来说,是被动接收这些数据的。然而,在有些应用中需要在线程运行的过程中动态地获取数据,如在下面代码的run方法中产生了3个随机数,然后通过Work类的process方法求这三个随机数的和,并通过Data类的value将结果返回。从这个例子可以看出,在返回value之前,必须要得到三个随机数。也就是说,这个 value是无法事先就传入线程类的。

   package mythread;
   
   class Data {
       public int value = 0;
   }
   
   class Work {
       public void process(Data data, Integer... numbers) {
           for (int n : numbers) {
               data.value += n;
           }
       }
   }
   
   public class MyThread3 extends Thread {
       private Work work;
   
       public MyThread3(Work work) {
           this.work = work;
       }
   
       public void run() {
           java.util.Random random = new java.util.Random();
           Data data = new Data();
           int n1 = random.nextInt(1000);
           int n2 = random.nextInt(2000);
           int n3 = random.nextInt(3000);
           work.process(data, n1, n2, n3);// 使用回调函数
           System.out.println(
                   String.valueOf(n1) + "+"
                   + String.valueOf(n2) + "+"
                   + String.valueOf(n3) + "=" + data.value);
       }
   
       public static void main(String[] args) {
           Thread thread = new MyThread3(new Work());
           thread.start();
       }
   }

  在上面代码中的process方法被称为回调函数。从本质上说,回调函数就是事件函数。在WindowsAPI中常使用回调函数和调用API的程序之间进行数据交互。因此,调用回调函数的过程就是最原始的引发事件的过程。在这个例子中调用了process方法来获得数据也就相当于在run方法中引发了一个事件。
分享到:
评论

相关推荐

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

    Java 多线程初学者指南之向线程传递数据的三种方法 在多线程编程中,向线程传递数据是一项非常重要的任务。与传统的同步开发模式不同,在多线程异步开发模式下,数据的传递和返回方式有很大的区别。因此,本文将...

    java向多线程中传递参数的三种方法详细介绍

    以下将详细介绍三种向Java多线程传递参数的方法。 1. **通过构造方法传递数据** 当创建Thread类或其子类的实例时,可以利用构造方法来传递数据。这些数据通常存储为类的成员变量,在`run()`方法中使用。例如: ``...

    java多线程编程之向线程传递数据的三种方法

    以下是三种主要的向线程传递数据的方法: 1. **通过构造方法传递数据** 这种方式是在创建线程对象时,通过构造函数将数据传入。例如,创建一个自定义的`Thread`子类,并在构造函数中接收数据,然后将其存储为类的...

    java多线程Demo

    Java线程有10个优先级(MIN_PRIORITY, NORM_PRIORITY, MAX_PRIORITY),默认优先级是NORM_PRIORITY。但是,线程优先级并不保证绝对的执行顺序,操作系统调度策略可能影响实际执行顺序。 7. join()方法: 一个线程...

    Java 模拟线程并发

    首先,Java中创建线程主要有两种方法。一种是通过继承Thread类,重写其run()方法,然后实例化并调用start()方法启动线程。例如: ```java class MyThread extends Thread { @Override public void run() { // ...

    java线程间等待并传递数据

    NULL 博文链接:https://huihuilou.iteye.com/blog/1934814

    java 多线程并发实例

    在Java中,创建线程主要有两种方式:继承Thread类和实现Runnable接口。在提供的实例中,我们可能会看到这两种方式的运用。 1. 继承Thread类:通过创建新的Thread子类并重写其run()方法,然后创建该子类的实例并调用...

    JAVA多线程编程技术PDF

    此外,还有java.util.concurrent工具包,包含如BlockingQueue等高级并发结构,它们简化了线程间的协作和数据传递。 死锁是多线程中的一个常见问题,当两个或更多线程相互等待对方释放资源而无法继续执行时,就会...

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

    在《向线程传递数据的三种方法》中提到的示例,创建一个工作类 `Work`,并在其中定义一个 `process` 方法,这个方法既接收输入数据,又返回计算结果。这种方式将数据传递和返回合并在一起,提高了代码的可读性和复用...

    Java 多线程 PPT

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

    Java多线程--等待所有子线程执行完的五种方法.docx

    在Java多线程编程中,有时我们需要确保所有子线程执行完毕后再进行后续操作,例如在并发测试、数据聚合或资源清理等场景。本篇文章将详细介绍五种在Java中等待所有子线程执行完的方法。 ### 方法一:使用`sleep`...

    Java的线程和Java AppletJava的线程和Java AppletJava的线程和Java Applet

    5. **线程状态**:Java线程有五种基本状态:新建、可运行、运行、阻塞和死亡。线程的状态转换反映了其生命周期的不同阶段。 6. **线程同步**:为了避免线程间的冲突,Java提供了多种同步机制,如`synchronized`...

    java 多线程示例

    Java线程有10个优先级,从`MIN_PRIORITY`(1)到`MAX_PRIORITY`(10),默认是`NORM_PRIORITY`(5)。优先级高的线程更可能被调度执行,但不保证。 4. **线程同步** 当多个线程访问共享资源时,可能会出现竞态条件,...

    Java多线程练习题

    在Java中,多线程的实现主要通过两种方式:继承Thread类和实现Runnable接口。理解并掌握多线程的使用对于任何Java开发者来说都至关重要。 一、线程的创建与启动 1. 继承Thread类:创建一个新的类,该类继承自Thread...

    Java多线程编程实战指南-核心篇

    Java的BlockingQueue阻塞队列可以实现线程间的生产者-消费者模式,通过put()和take()方法实现数据的传递。此外,Phaser、CyclicBarrier和CountDownLatch等同步辅助类也是线程间协调的重要工具。 线程池是Java并发...

    Java的多线程(java基础)

    每个线程由虚拟CPU、执行的程序代码和处理的数据三部分组成。通过创建Thread类的实例,我们可以启动、控制和结束线程,实现任务的并发执行。 在Java中创建线程主要有两种方式: 1. 继承Thread类:自定义一个新的类...

    java多线程的两种实现

    Java线程有10个优先级,`Thread.MIN_PRIORITY` (1)到`Thread.MAX_PRIORITY` (10),默认优先级是`Thread.NORM_PRIORITY` (5)。不过,线程优先级对实际调度的影响并不大,因为大多数操作系统不支持优先级调度。 6. *...

    Hystrix跨线程传递数据解决方案:HystrixRequestContext.docx

    ### Hystrix跨线程传递数据解决方案:HystrixRequestContext #### 前言 在分布式系统中,为了提高系统的稳定性和响应性,通常会采用微服务架构,并且使用断路器模式来隔离不同服务之间的故障传播。Netflix 的 ...

    给Thread线程传递数据

    在Java或C#等面向对象的语言中,有多种方法可以实现给线程传递数据。本篇将详细讲解两种主要的方式:通过构造函数传参和使用自定义类。 首先,让我们来看看**通过构造函数传递数据**的方法。在Java中,我们可以创建...

    JAVA多线程实现数据库之间的数据互导、连接池、及多表插入数据库功能

    - **线程通信**:使用wait()、notify()和notifyAll()方法实现线程间的通信,或者使用BlockingQueue进行数据传递。 2. **数据库互导**: - **JDBC(Java Database Connectivity)**:它是Java连接数据库的标准API...

Global site tag (gtag.js) - Google Analytics