精华内容
下载资源
问答
  • 线程数据传递主要分为向线程传递参数和从线程获取返回值; 1、 向线程中传递参数的方法主要有三种: 通过构造函数传递 在调用start方法之前通过线程类的构造方法将数据传入线程。 public class MyThread ...

    线程间的数据传递主要分为向线程传递参数和从线程获取返回值;

    1、 向线程中传递参数的方法主要有三种:
    • 通过构造函数传递
      在调用start方法之前通过线程类的构造方法将数据传入线程。
    public class MyThread 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 MyThread("world");
    	   thread.start();        
    	 }
    }
    
    • 通过变量和方法传递
    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();
        }
    }
    
    • 调用回调函数传递数据
    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方法来获得数据也就相当于在run方法中引发了一个事件。

    2、从线程中获取返回值的方法主要有:
    • 使用join()方法
    public class MyThread3 extends Thread {
        private String value1;
        private String value2;
    
        public void run() {
            value1 = "value1";
            value2 = "value2";
        }
    
        public static void main(String[] args) throws Exception {
            MyThread3 thread = new MyThread3();
            thread.start();
            thread.join();
            System.out.println("value1:" + thread.value1);
            System.out.println("value2:" + thread.value2);
        }
    }
    

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

    • 使用回调函数
      与前边介绍的一致,灵活运用即可。
    展开全文
  • Java线程间数据传递

    千次阅读 2016-08-03 21:56:22
    线程共享数据Java中共享数据,可以使用一个共享对象,或者使用一个阻塞队列。接下来看一个日志的例子。其中主线程可以记录日志,而另外开启了一个线程进行日志的输出public class LogService { private final ...

    ###线程共享数据
    Java中共享数据,可以使用一个共享对象,或者使用一个阻塞队列。接下来看一个日志的例子。其中主线程可以记录日志,而另外开启了一个线程进行日志输出

    public class LogService {
    
    	private final BlockingQueue<String> queue;
    	
    	private final LoggerThread logger;
    	
    	//关闭标记
    	private volatile boolean isShutDown;
    	
    	public void start() {
    		logger.start();
    	}
    	
    	public void stop() {
    		isShutDown = true;
    		logger.interrupt();
    	}
    	
    	public void log(String msg) throws InterruptedException {
    		queue.put(msg);
    	}
    
    	public LogService() {
    		queue = new LinkedBlockingQueue<String>();
    		logger = new LoggerThread();
    	}
    
    	private class LoggerThread extends Thread {
    		@Override
    		public void run() {
    			try {
    				while (true) {
    					if (isShutDown)
    						break;
    					System.out.println(queue.take());
    				}
    			} catch (InterruptedException e) {
    				e.printStackTrace();
    			}
    		}
    		
    	}
    }
    

    ###延迟处理
    有时一个任务开启一个线程执行,需要等待数据返回再进行处理,但又希望主线程可以继续跑下去。这时可以使用Future进行处理。代码

    public class GetData {
    	
    	private final ExecutorService executor = Executors.newSingleThreadExecutor();
    	
    	public Future<String> getData() {
    		return executor.submit(new Callable<String>() {
    			@Override
    			public String call() throws Exception {
    				System.out.println("my data!");
    				return "hello world!";
    			}
    		});
    	}
    }
    

    测试

    public static void main(String[] args) throws InterruptedException, ExecutionException {
    		GetData data = new GetData();
    		Future<String> future = data.getData();
    		
    		//做其他事情
    		System.out.println("do something!");
    		
    		String str = future.get();
    		System.out.println(str);
    	}
    

    ###其他参考
    《Java并发编程实战》

    展开全文
  • 这个demo介绍了通过Handler在线程之间传递消息,demo中一个三个线程,主线程,发送消息的分线程,接收消息的分线程。发送消息的分线程会通知主线程更改标签文字,同时会通知接收消息的分线程更改进度条的进度。
  • 小白使用bundle在线程之间传递数据。 ** 实现从云端数据库中拿出数据,并将数据传递给UI主线程,并更新UI界面。 因为Android 3.0以后使用网络相关的东西不能直接在主线程实现。所以需要创建一个子线程,从云数据库中...

    **

    小白使用bundle在线程之间传递数据。

    **
    实现从云端数据库中拿出数据,并将数据传递给UI主线程,并更新UI界面。

    因为Android 3.0以后使用网络相关的东西不能直接在主线程实现。所以需要创建一个子线程,从云数据库中获取数据。

    创建一个GetDataThread线程类

    public class GetDataThread extends Thread {
    	 //重点
        private Handler handler ;
        private String type;
        /* 传入两个参数,第一个是用于通信的handler,第二个是动态类型 */
        public GetDataThread(Handler h,String type){
            this.handler = h ;
            this.type = type;
         }
        }
    

    想要在线程间传递数据,最主要的是需要把主线程的Handler传进GetDataThread类中,而不是直接new一个新的handler。
    在拿到handler后就能在handler中存放数据了。

    	    Bundle bundle = new Bundle();
            Message message=new Message();
            //listitem是一个ArrayList<>
            bundle.putSerializable("listitem",listitem);
    

    这里需要注意向bundle中存放不同类型的数据,要使用不同的方法。
    字符串用putString。。等,详情百度。。

    在主线程中,只要声明一个全局变量handler并重写handleMessage方法,在方法的msg中就可以获取数据了。

     @SuppressLint("HandlerLeak")
        private Handler handler = new Handler(){
            @Override
            public void handleMessage(Message msg) {
                Bundle bundle = msg.getData();
                List<Map<String,Object>> listitem = (List<Map<String, Object>>) bundle.getSerializable("listitem");
     
    
            }
        };
    
    展开全文
  • 如何给线程传递数据 1.通过构造方法传递数据 在创建线程时,必须要创建一个Thread类的或其子类的实例。因此可以在调用start方法之前,通过 线程类的构造方法 将数据传入线程。并将传入的数据使用 成员变量接收 ,...

    一.如何给线程传递数据

    1.通过构造方法传递数据

    在创建线程时,必须要创建一个Thread类的或其子类的实例。因此可以在调用start方法之前,通过 线程类的构造方法 将数据传入线程。并将传入的数据使用 成员变量接收 ,以便线程体使用

    /**
     * TODO 测试线程传递参数1-通过构造方法传递数据
     */
    public class TestThreadPassParam1 extends Thread {
        //用于接受构造方法传进来的数据
        private String name;
    
    	//构造方法
        public TestThreadPassParam1(String name) {
            this.name = name;
        }
        
        //线程体
        @Override
        public void run() {
            System.out.println("hello " + name);
        }
        
        public static void main(String[] args) {
            Thread thread = new TestThreadPassParam1("world");
            thread.start();
        }
    }
    

    通过构造方法传递数据的,在线程运行之前这些数据就就已经到位了,这样就不会造成数据在线程运行后才传入的现象。如果要传递更复杂的数据,可通过类方法或类变量来传递数据。

    2.通过变量和方法传递数据

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

    /**
     * @Description TODO 测试线程传递参数2-通过变量和方法传递数据
     */
    public class TestThreadPassParam2 extends Thread {
       //传递参数
        private String food;
    
        public void setFood(String food) {
            this.food = food;
        }
    
    	//线程体
        @Override
        public void run() {
            System.out.println("吃" + food);
        }
    
        public static void main(String[] args) {
            TestThreadPassParam2 myThread = new TestThreadPassParam2();
            myThread.setFood("包子");
    
            Thread thread = new Thread(myThread);
            thread.start();
        }
    }
    

    3.通过回调函数传递数据

    上面两种向线程传递数据的方法是最常用的。都是在主线程main()中主动将数据传入线程类的。这对于线程来说,是被动接收这些数据的。然而,在有些应用中需要在线程运行的过程中动态地获取数据.

    如: 在下面代码的run方法中产生了3个随机数,然后通过Work类的process方法求这三个随机数的和,并通过Data类的value将结果返回。从这个例子可以看出,在返回value之前,必须要得到三个随机数。也就是说,这个value是无法事先就传入线程类的。

    import java.util.Random;
    /**
     * @Description TODO 测试线程传递参数3-通过回调函数传递数据
     */
    public class TestThreadPassParam3 extends Thread {
        //传递参数
        private Work work;
    
        //构造方法
        public TestThreadPassParam3(Work work) {
            this.work = work;
        }
    
        //线程体
        public void run() {
            //声明Data对象
            Data data = new Data();
    
            //声明随机对象
            Random random = new Random();
            int n1 = random.nextInt(1000);//随机数1
            int n2 = random.nextInt(2000);//随机数2
            int n3 = random.nextInt(3000);//随机数3
    
            //线程内调用work对象的.process方法
            work.process(data, n1, n2, n3);   // 使用回调函数
    
            System.out.println(n1 + "+" + n2 + "+" + n3 + "=" + data.value);
        }
    
        public static void main(String[] args) {
            Thread thread = new TestThreadPassParam3(new Work());
            thread.start();
        }
    }
    
    //计数器
    class Data {
        public int value = 0;
    }
    
    //在线程内回调,用于将numbers的值累加到Data.value
    class Work {
        public void process(Data data, Integer... numbers) {
            for (Integer n : numbers) {
                data.value += n;
            }
        }
    }
    

    在上面代码中的process方法被称为回调函数。从本质上说,回调函数就是事件函数。调用回调函数的过程就是最原始的触发事件的过程。在这个例子中调用了process方法来获得数据也就相当于在run方法中引发了一个事件。

    二.如何让线程返回数据

    从线程中返回数据和向线程传递数据类似,也可以通过类成员以及回调函数来返回数据,但类成员在返回数据和传递数据时有一些区别

    1.主线程等待

    使用这种方法返回数据需要在线程完成后才能通过类变量或方法得到数据

    /**
     * TODO 测试线程返回数据1-通过主线程等待返回数据
     */
    public class TestThreadReturnData1 extends Thread {
        private Count count;
    
        TestThreadReturnData1(Count count) {
            this.count = count;
        }
    
        @Override
        public void run() {
            for (int i =0 ;i<10;i++) {
                this.count.setValue(this.count.getValue()+1);
            }
        }
    
        public static void main(String[] args) throws InterruptedException {
            Count count = new Count();
            Thread thread = new Thread(new TestThreadReturnData1(count));
            thread.start();
    
            // 获取子线程的返回值:主线程等待法
            while (count.getValue() == 0) {
                Thread.sleep(1000);
            }
            System.out.println(count.getValue());
            System.out.println("主线程执行完毕");
        }
    }
    
    //计数器
    @Data
    class Count {
        public int value = 0;
    }
    

    在这里插入图片描述

    2.Join方法阻塞当前线程以等待子线程执行完毕

    使用join方法可以让子线程执行完毕后再执行主线程,本质和通过循环判断一样

    import lombok.Data;
    
    /**
     * @Description TODO 测试线程返回数据1-通过Join方法阻塞当前线程以等待子线程执行完毕返回数据
     */
    public class TestThreadReturnData2 extends Thread {
        private Count2 count;
    
        TestThreadReturnData2(Count2 count) {
            this.count = count;
        }
    
        @Override
        public void run() {
            for (int i =0 ;i<10;i++) {
                this.count.setValue(this.count.getValue()+1);
            }
        }
    
        public static void main(String[] args) throws InterruptedException {
            Count2 count = new Count2();
            Thread thread = new Thread(new TestThreadReturnData2(count));
            thread.start();
    
            // 获取子线程的返回值:Thread的join方法来阻塞主线程,直到子线程返回
            thread.join();
    
            System.out.println(count.getValue());
            System.out.println("主线程执行完毕");
        }
    }
    
    //计数器
    @Data
    class Count2 {
        public int value = 0;
    }
    

    在这里插入图片描述

    3.使用Callable接口和FutureTask

    在JDK1.5加入了Callable接口,实现该接口并重写call()方法也能创建新线程,并且该方法是有返回值的!

    import java.util.concurrent.Callable;
    import java.util.concurrent.ExecutionException;
    import java.util.concurrent.FutureTask;
    
    public class CallableAndFutureReturnData implements Callable<String> {
        public static void main(String[] args) throws ExecutionException, InterruptedException {
            /***
             * FutureTask 实现了 Runnable接口,所以新建线程的时候可以传入FutureTask
             * FutureTask重写的run方法中实际是调用了Callable接口在call()方法,所以执行线程的时候回执行call方法的内容
             */
    
            FutureTask<String> task = new FutureTask<String>(new CallableAndFutureReturnData());
            new Thread(task).start();
    
            if (!task.isDone()) {
                System.out.println("task has not finished, please wait!");
            }
    
            System.out.println("task return: " + task.get());
        }
    
        @Override
        public String call() throws Exception {
            String value = "over";
            System.out.println("Ready to work");
            Thread.currentThread().sleep(5000);
            System.out.println("task done");
            return value;
        }
    }
    

    在这里插入图片描述
    这里需要关注FutrueTask的两个方法:

    • isDone:利用state变量判断call方法有没有被执行
    • get:如果call方法已经执行完就返回call方法的返回值,如果call方法没有执行完就一直阻塞

    4.使用线程池

    public class ThreadPoolDemo {
        public static void main(String[] args) {
            //创建线程池
            ExecutorService newCachedThreadPool = Executors.newCachedThreadPool();
            //通过线程池管理线程MyCallable
            Future<String> future = newCachedThreadPool.submit(new MyCallable());
    
            //如果提交的任务未完成
            if (!future.isDone()) {
                System.out.println("task has not finished, please wait!");
            }
    
            try {
                System.out.println(future.get());
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (ExecutionException e) {
                e.printStackTrace();
            } finally {
                //关闭线程池
                newCachedThreadPool.shutdown();
            }
        }
    }
    
    class MyCallable implements Callable<String> {
        //线程体
        @Override
        public String call() throws Exception {
            String value = "over";
            System.out.println("Ready to work");
            Thread.currentThread().sleep(5000);
            System.out.println("task done");
            return value;
        }
    }
    
    
    展开全文
  • C++线程间通讯:数据传递

    千次阅读 2018-05-08 16:26:40
    处于这个条件,各个线程函数都可以操作全局变量,达到数据传递的问题。不过由于现代CPU的时间片轮转线程抢占机制,全局变量的操作需要注意同步的问题。 关于线程同步的问题,锁机制实现了一部分功能,但是由于...
  • Qt多线程间传递变量方法总结

    千次阅读 2018-01-09 11:50:12
    Qt线程共享数据主要有两种方式:一是使用共享内存。即使用一个两个线程都能够共享的变量(如全局变量),这样两个线程都能够...二是使用singal/slot机制,把数据从一个线程传递到另外一个线程。 第一种办法在各个编
  • 线程间数据传递会产生两个问题: 1)竞争 两个线程同时修改一个变量,后一个人的修改会覆盖前一个人的修改,这种情况叫做竞争。 2)死锁 当一个线程占用资源A而请求资源B,另一个线程占用资源B而请求资源A,两...
  • 不同线程之间传递数据

    千次阅读 2013-05-15 19:41:23
    一般情况下,在线程间是不能交换数据的,不过在相同应用程序域中的线程则可以共享应用程序域的数据。我们可以通过AppDomain的GetData和SetData方法来实现这一功能。具体见源代码。 using System; using System....
  • 在多线程的异步开发模式下,数据传递和返回和同步开发模式有很大的区别。由于线程的运行和结束是不可预料的,因此,在传递和返回数据时就无法象函数一样通过函数参数和return语句来返回数据
  • 线程间通信——数据传递和同步

    千次阅读 2012-02-01 10:33:54
    线程通信会产生两个问题:一个是如何传递数据,另一个是如何同步。 1、线程数据传递 线程被创建后,我们无法利用线程的控制函数将数据从一个线程传递到另一个线程,然而,.NET本身的一个重要特性就是完全...
  • c# 窗口间传递数据

    2013-06-21 10:09:27
    c# 利用委托,两个窗口传递数据,同样适用于多线程传递数据
  • 有时候我们需要不同的线程之间进行数据的传送,使得数据合并,达到完成的数据,这里简单记录下线程之间的传递。基本思想通过槽函数也让线程1与线程2绑定发送数据与接受数据函数。 创建一个QT Widgets工程,添加两个...
  • Qt线程间共享数据

    千次阅读 2017-11-29 14:34:56
    Qt线程间共享数据1. 数据共享注意点像 QString 等这些 Qt 本身定义的类型,直接传送即可。但如果自定义的类型想使用 signal/slot 来传递的话,则不能直接使用。 typedef unsigned short u16;以 u16 为例: 步骤: ...
  • c#线程间传递参数

    千次阅读 2010-04-22 21:25:00
    线程操作主要用到Thread类,他是定义在System.Threading.dll下。... Thread (ParameterizedThreadStart) 初始化 Thread 类的新实例,指定允许对象在线程启动时传递线程的委托。 Thread (ThreadStart)
  • 1、申请全局数据块 比如队列 2、利用共享内存(文件映射)技术 同时对共享资源的访问做好同步与互斥操作 
  • Spring Cloud 之 Hystrix 跨线程传递数据

    千次阅读 2018-10-29 20:24:55
    本文以一个技术场景来学习 Hystrix 跨线程传递数据的知识。将先简述ThreadLocal、InheritableThreadLocal跨父子线程传递数据,再进入主题。 基于Spring Boot 2.0.6.RELEASE, Spring Cloud Finchley.SR1。 技术场景 ...
  • 为了在需求中更好的传递数据,减少重复请求数据库获取数据的操作,先在后端服务的请求中关于拦截器和过滤器有以下的生命周期: 1.Filter Pre (过滤器) chain.doFilter(request, response) 前的逻辑 2.service ...
  • MFC 多线程之间通过消息传递数据

    热门讨论 2013-04-11 10:23:12
    MFC编程,一个对话框程序,多线程之间通过消息传递数据
  • 线程传参自定义数据 • 1、自定义数据类型 • 2、传递自定义数据类型的指针 • 3、把数据内存指针转换为新数据内存指针 • 4、赋给新的自定义数据变量源码: .子程序 子程序1 .参数 a, 整数型 .局部变量 C, ...
  • 线程间数据传输

    千次阅读 2017-06-07 23:08:39
    java中提供了各种各样的输入/输出流stream,是我们能够很方便的对数据进行操作,其中管道流pipeStream是一种特殊的流,用于在不同线程间直接传送数据。一个线程发送数据到输出管道,另一个线程从输入管道中读取数据...
  • //现程槽传递数据 #region 向线程槽中放入对象,从线程槽中获取对象 // public static void setObjectData(string slotName, object objectData) { LocalDataStoreSlot findSlot = 
  • 在传统的同步开发模式下,当我们调用一个函数时,通过这个函数的参数将数据传入,并通过这个函数的返回值来返回最终...本文就以上原因介绍了几种用于向线程传递数据的方法,在下一篇文章中将介绍从线程中返回数据的方法
  • Qt多线程线程之间的传递数据

    千次阅读 2020-08-13 15:22:35
    .hpp #ifndef MAINWINDOW_H #define MAINWINDOW_H #include #include #include static QVector<int>myArray; static QVector<int>myAnotherArray; namespace Ui { class MainWindow;... } 运行结果 线程中生成的随机数
  • 线程传递数据的三种方法

    千次阅读 2018-06-08 14:47:45
    在传统的同步开发模式下,当我们调用一个函数时,通过这个函数的参数将数据传入,并通过这个函数的返回值来返回最终...本文就以上原因介绍了几种用于向线程传递数据的方法,在下一篇文章中将介绍从线程中返回数据的...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 447,336
精华内容 178,934
关键字:

线程间传递数据