精华内容
下载资源
问答
  • 因此可以调用start方法之前,通过 线程类的构造方法 将数据传入线程。并将传入的数据使用 成员变量接收 ,以便线程体使用 /** * TODO 测试线程传递参数1-通过构造方法传递数据 */ public class ...

    一.如何给线程传递数据

    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;
        }
    }
    
    
    展开全文
  • java多线程采集+线程同步-【多线程数据采集之四】

    万次阅读 多人点赞 2012-11-21 14:00:34
    java多线程数据抓取。  java多线程采集+数据同步+线程同步【多线程数据采集之四】 主要讲解多线程抓取,多线程同步,多线程启动,控制等操作。 文章栏目列表:...

    前些日子讲解了java数据抓取, 今天就讲解最核心的。 java多线程数据抓取。 

    java多线程采集+数据同步+线程同步【多线程数据采集之四】

    主要讲解多线程抓取,多线程同步,多线程启动,控制等操作。

    文章栏目列表:http://blog.csdn.net/column/details/threadgrab.html


    先讲解第一步,线程类。   核心数据抓取线程。

    这个例子主要讲解的是  对设定的天数的数据抓取。 从当前日期往后推。

    每个线程负责一天的数据任务抓取。

    七七八八网http://www.qi788.com

    源代码如下:

    1、线程类

    package com.yjf.util;
    import java.util.Date;
    import java.util.List;
    
    
    public class GetWebThread extends Thread{
    	
    	/**
    	 * 线程
    	 */
    	public void run(){
    		try {
    			while (true) {
    				int day = 0;
    				long time1 = new Date().getTime();
    				//用来同步抓取线程
    				synchronized("searchthead"){
    					Main.thisdaycount++;
    					if(Main.thisdaycount>Main.daycount){
    				    	break;
    			    	}
    					System.out.println("开始查询第"+(Main.thisdaycount)+"天");
    					Thread.sleep(133);
    					day = Main.thisdaycount-1;
    				}
    				//获取抓取的时间
    				String datetext = TimeUtil.date.format(TimeUtil.addDaysForDate(day));
    				String[] txt =FileUtil.getCityByTxtFile();
    				for(int t=0;t<txt.length;t++){
    
    					String[] way = txt[t].split("\\|");
    					String start = way[0];
    					String end = way[1];
    					//抓取到的数据列表
    					List<DataBean> datalist = Main.getDataList(datetext, start, end);
    					if(datalist!=null){
    						Main.isadsl = 0;
    						CheckAdsl.adsllasttime = new Date().getTime();
    						FileUtil.addDataToFileCsv(datalist);
    						Main.log.printLog("===="+datetext+"="+start+"="+end+"="+t+"=数据总数:"+datalist.size());
    					}else{
    							Thread.sleep(11);
    							AdslThead.isadsl = true;
    							Thread.sleep(11);
    							//判断是否正在拨号 并暂停线程
    							while (AdslThead.isadsl) {
    								Thread.sleep(5000);
    							}
    						t--;
    					}
    				}
    				long time2 = new Date().getTime();
    				Main.log.printLog(datetext+"==查询完毕=========耗时"+(time2-time1));
    			}
    		} catch (Exception e) {
    			Main.log.printLog(e.getMessage());
    			e.printStackTrace();
    		}
    	}
    	
    }

    第二步, 准备线程启动。 

    控制线程数量。 

    尖锋网http://www.jfong.cn

    查询数据总天数。

    设置拨号状态等。

    2、线程启动类。 包括启动,控制,停止

    package com.yjf.util;
    
    import java.io.BufferedInputStream;
    import java.io.FileInputStream;
    import java.io.InputStream;
    import java.util.ArrayList;
    import java.util.Date;
    import java.util.List;
    import java.util.Properties;
    import java.util.Timer;
    
    
    public class Main {
    	private static boolean isRunGrabThread = true;     //抓取线程是否执行完毕
    	public static int threadCount = 3;   //线程数量
    	public static int daycount = 30;         //查询总天数
    	public static int thisdaycount = 0;
    	public static int isadsl = 0;
    	public static int adslcount = 1;
    	
    	
    		public static void main(String[] args) {
    			try {
    				
    				startThead();//启动抓取数据主线程
    			} catch (Exception e) {
    				e.printStackTrace();
    			}
    		}
    		
    		
    		public static void startThead(){
    			Thread[] grabThreads= new Thread[threadCount];	
    			try{		  
    				//开启-数据抓取子线程
    			  	for(int i=0;i<grabThreads.length;i++){
    				  	Thread searchThread=new GetWebThread();
    			  		grabThreads[i] = searchThread;
    			  		grabThreads[i].setDaemon(true);
    			  		grabThreads[i].start();
    			  	}
    				
    			  	isRunGrabThread = true;
    			  	
    			  	//监控子线程,全部完成程序退出
    			    WhileLoop:		    			    	
    			    	
    			    while(true){
    			    	
    			    	//拨号策略控制
    			    	//reconnectControl();	
    			    	
    					//判断子线程是否运行完成
    			    	for(int i=0;i<threadCount;i++){
    			    		if(grabThreads[i].isAlive()){
    			    			Thread.sleep(3*1000);
    			    			continue WhileLoop;
    			    		}
    			    	}
    
    			    	//所有抓取线程执行完毕
    			    	isRunGrabThread = false;
    			    	
    			    	//子线程执行完毕则退出
    			    	break;
    			    }
    			}
    			catch (Exception e) {
    				System.out.println("main主线程--系统异常!");
    			}
    		}
    		
    		
    
    }
    
    
    【多线程数据采集之四】java多线程采集+数据同步+线程同步


    展开全文
  • 线程私有数据

    千次阅读 2012-07-23 20:37:15
    因为线程ID不能保证是小而连续的整数,所以不能简单的分配一个线程数据数组,用线程ID作为数组的索引。即使线程ID确实是小而连续的整数,可能还希望有一些额外的保护,以防止某个线程的数据和其它线程


    一个标准的线程由 线程ID 当前指令指针(PC) 寄存器集合 和 堆栈组成

    见--码农自我修养 线程部分
    1.为什么需要线程私有数据:

    原因一:有时候需要维护基于每个线程的数据,用线程ID作为索引。因为线程ID不能保证是小而连续的整数,所以不能简单的分配一个线程数据数组,用线程ID作为数组的索引。即使线程ID确实是小而连续的整数,可能还希望有一些额外的保护,以防止某个线程的数据和其它线程的数据相混淆。
    原因二:可以让基于进程的接口适应多线程环境,比如errno,线程出现以前errno被定义成进程环境中全局可访问的整数,线程出现以后,为了让线程也能使用那些原本基于进程的系统调用和库例程,errno被重新定义成线程私有数据。
    (参考APUE2)
    2.进程中的所有线程都可以访问进程的整个地址空间,除非使用寄存器(一个线程真正拥有的唯一私有存储是处理器寄存器),线程没有办法阻止其它线程访问它的数据,线程私有数据也不例外,但是管理线程私有数据的函数可以提高线程间的数据独立性。

    3.int pthread_key_create(pthread_key_t *keyp, void (*destructor)(void *));
    在分配(malloc)线程私有数据之前,需要创建和线程私有数据相关联的键(key),这个键的功能是获得对线程私有数据的访问权。
    如果创建一个线程私有数据键,必须保证Pthread_key_create对于每个Pthread_key_t变量仅仅被调用一次,因为如果一个键被创建两次,其实是在创建两个不同的键,第二个键将覆盖第一个键,第一个键以及任何线程可能为其关联的线程私有数据值将丢失。
    创建新键时,每个线程的数据地址设为NULL。


    4.关于析构函数void (*destructor)(void *):
    当线程退出时,如果线程私有数据地址被置为非NULL值,那么析构函数就会被调用。
    当线程调用pthread_exit或者线程执行返回,正常退出时,析构函数就会被调用,但是如果线程调用了exit系列函数或者abort或者其它非正常退出时,就不会调用析构函数。

    5.线程退出时,线程私有数据的析构函数将按照OS实现定义的顺序被调用。析构函数可能调用另外一个函数,而该函数可能创建新的线程私有数据而且把这个线程私有数据和当前的键关联起来。当所有的析构函数都调用完成以后,系统会检查是否有非NULL的线程私有数据值与键关联,如果有的话,再次调用析构函数,这个过程一直重复到线程所有的键都为NULL值线程私有数据,或者已经做了PTHREAD_DESTRUCTOR_ITERATIONS中定义的最大次数的尝试.

    当下爱你成退出时,Pthreads在进程汇总检查所有的线程私有数据键,并且将不是NULL的线程私有数据简置NULL,然后调用键的destructor函数。

    6.int pthread_delete(pthread_key_t *keyp),注意调用pthread_delete不会激活与键关联的析构函数,容易造成内存泄露。
    当删除线程私有数据键的时候,不会影响任何线程对该键设置的线程私有数据值,甚至不影响调用线程当前键值,所以容易造成内存泄露,如果你不记得释放所有线程内与该键相关联的私有数据空间的话。
    使用已经删除的私有数据键将导致未定义的行为。

    编程建议:最后不删除线程私有数据键!!!尤其当一些线程仍然持有该键的值时,就更不该释放该键!!!

    7.需要确保分配的键不会由于初始化阶段的竞争而发生变动。(使用pthread_once避免)
    容易发生竞争的代码段:
    void destructor(void *);

    pthread_key_t key;
    int      flag;

    int threadfun(void *arg)
    {
    if(!flag){
           flag = 1;
           pthread_key_create(&key, destructor);
        }
    }


    使用pthread_once:
    void destructor(void *);

    pthread_once_t initonce = PTHREAD_ONCE_INIT;
    pthread_key_t  key;

    void thread_once(void)
    {
    pthread_key_create(&key, destructor);
    }

    int threadfun(void *arg)
    {
    pthread_once(&initonce, thread_once);
    ...
    }

    8.void *pthread_getspecific(pthread_key_t key);
      int pthread_setspecific(pthread_key_t key, const void *value);

    if(pthread_getspecific(key) == NULL){
        printf("需要调用pthread_setspecific");
    }
    展开全文
  • 线程中返回数据和向线程传递数据类似。也可以通过类成员以及回调函数来返回数据。但类成员返回数据和传递数据时有一些区别,下面让我们来看看它们区别在哪
  • 线程私有数据TSD

    千次阅读 2013-11-03 10:50:21
    线程程序中,我们经常要用到"全局变量"以实现多个函数间共享数据线程环境下,由于数据空间是共享的,因此全局变量也为所有线程所共有。但有时应用程序设计中有必要提供线程私有的全局变量,仅某个线程中...

           在单线程程序中,我们经常要用到"全局变量"以实现多个函数间共享数据。在多线程环境下,由于数据空间是共享的,因此全局变量也为所有线程所共有。但有时应用程序设计中有必要提供线程私有的全局变量,仅在某个线程中有效,但却可以跨多个函数访问,比如程序可能需要每个线程维护一个链表,而使用相同的函数操作,最简单的办法就是使用同名而不同变量地址的线程相关数据结构。这样的数据结构可以由Posix线程库维护,称为线程私有数据(Thread-specific Data,或TSD)。

         下面的系统调用将实现TSD:

         创建和注销
                 Posix定义了两个API分别用来创建和注销TSD:
                          int pthread_key_create(pthread_key_t *key, void (*destr_function) (void *))
                    该函数从TSD池中分配一项,将其值赋给key供以后访问使用。如果destr_function不为空,在线程退出(pthread_exit())时将以key所关联的数据为参数调用destr_function(),以释放分配的缓冲区。不论哪个线程调用pthread_key_create(),所创建的key都是所有线程可访问的,但各个线程可根据自己的需要往key中填入不同的值,这就相当于提供了一个同名而不同值的全局变量。在LinuxThreads的实现中,TSD池用一个结构数组表示:

                注销一个TSD采用如下API:
                         int pthread_key_delete(pthread_key_t key)
                    这个函数并不检查当前是否有线程正使用该TSD,也不会调用清理函数(destr_function),而只是将TSD释放以供下一次调用pthread_key_create()使用。在LinuxThreads中,它还会将与之相关的线程数据项设为NULL。


          TSD的读写都通过专门的Posix Thread函数进行,其API定义如下:

                         int pthread_setspecific(pthread_key_t key, const void *pointer)
                         void * pthread_getspecific(pthread_key_t key)
                    写入(pthread_setspecific())时,将pointer的值(不是所指的内容)与key相关联,而相应的读出函数则将与key相关联的数据读出来。数据类型都设为void *,因此可以指向任何类型的数据。

    一个实例:

    #include<iostream>
    #include<pthread.h>
    #include<unistd.h>
    #include<boost/noncopyable.hpp>
    using namespace std;
    using namespace boost;
    template<typename T>
    class ThreadSpecificData:boost::noncopyable{
        public:
            ThreadSpecificData(){
                pthread_key_create(&key,&destructor);
            }
            ~ThreadSpecificData(){
                pthread_key_delete(key);
            }
            T& value(){
                T* data=static_cast<T*>(pthread_getspecific(key));//static_cast < type-id > ( expression )将expression转换为type-id类型,但没有运行时类型检查来保证转换的安全性
                if(!data){//这里采用单件模式,因为不涉及跨线程所以是安全的单件模式
                    T* newobj=new T();
                    pthread_setspecific(key,newobj);
                    data=newobj;
                }
                return *data;
            }
        private:
            static void destructor(void* x){
                T* obj=static_cast<T*>(x);
                delete obj;
            }
        private:
            pthread_key_t key;
    };
    class test{//模板实例化类T
        public:
            test(){
                cout<<"test()"<<endl;
            }
            ~test(){
                cout<<"~test()"<<endl;
            }
    };
    void* worker1(void* arg){
        ThreadSpecificData<test> one;
        test temp=one.value();//在子线程中构造和析构
        cout<<pthread_self()<<endl;
    }
    int main(){
        pthread_t pid;
        pthread_create(&pid,NULL,worker1,NULL);
        pthread_join(pid,NULL);
        cout<<"main pthread "<<pthread_self()<<endl;//输出主线程号
        return 0;
    }

    程序输出:

    test()          //在子线程中构造
    139882799634176
    ~test()        //在子线程中销毁
    main pthread 139882816374592


    一个应用是:在网络编程中,服务端的主线程叫一批客户连接类交给一个子线程,这些子线程负责连接和关闭这些客户连接。

    展开全文
  • 大漠多线程线程传参数据变量地址

    千次阅读 2020-05-30 09:18:52
    • 2、启动线程(,变量数据地址,,) • 3、指针到文本(变量数据地址) 511遇见易语言多线程大漠多线程 课程源码: .版本 2 .支持库 spec .支持库 EThread .程序集 窗口程序集_启动窗口 .子程序 _按钮1_被...
  • 线程数据传输

    千次阅读 2017-06-07 23:08:39
    java中提供了各种各样的输入/输出流stream,是我们能够很方便的对数据进行操作,其中管道流pipeStream是一种特殊的流,用于不同线程间直接传送数据。一个线程发送数据到输出管道,另一个线程从输入管道中读取数据...
  • 线程数据竞争问题

    千次阅读 2016-11-09 17:09:37
    这个问题涉及到linux c中, 用for循环创建多个线程并传参数时会遇到的数据竞争问题. 本文给出该问题的分析, 几段相关的错误代码的分析, 并结合redis的BIO模块代码给出总结. 第一种错误的写法我们的目标是一个for...
  • 线程插入数据

    千次阅读 2019-03-20 14:02:20
    高并发多线程插入数据写法示例 使用方法 // 固定声明10个线程 private ExecutorService executorService = Executors.new FixedThreadPool(10); private ThreadPoolExecutor executor = (ThreadPoolExecutor)...
  • 线程间共享数据

    千次阅读 2014-02-07 10:48:42
    若每个线程执行的代码相同,共享数据就比较方便。可以使用同一个Runnable对象,这个Runnable对象中就有那个共享数据。 public class MultiThreadShareData1 {  public static void main(String[] args)  {  ...
  • 线程操作数据拷贝要加线程

    千次阅读 2014-06-05 00:15:03
    debug三天之后,今天终于发现了自己开的两个线程(一个接收数据,一个处理数据)所处理的数据并不相等。用compare比较后发现数据有所偏差,处理线程数据存成文件之后隔一段都要比接收线程少一点。少的频率跟线程...
  • C#多线程数据采集器

    2008-02-16 16:05:27
    C#多线程数据采集器,想了解C#多线程编程的朋友可以参考一下!
  • 多线程的那点儿事(之多线程数据结构)

    万次阅读 多人点赞 2011-12-09 21:05:35
    所以,我们编写多线程的时候,就需要考虑一下如何在数据结构中插入锁。当然,有些数据结构是没有锁的,所以自然这个锁并不一定是必须的。  比如说,我们编写一个多线程堆栈,应该怎么做呢, typedef s
  • 线程之间的数据共享

    万次阅读 2018-08-03 22:32:48
    线程之间的数据共享问题可以分为两类,一类是执行代码一直的的线程共享线程共享,另一类是执行代码不一致的线程共享问题。接下来分别进行总结。 一、执行代码一致的线程共享问题 如果每个线程执行的代码执行的代码...
  • Java 从线程返回数据

    万次阅读 2017-12-06 20:59:50
    线程中返回数据的两种方法 1、通过类变量和类方法返回数据 2、通过回调函数返回数据
  • 【Linux】Linux线程私有数据

    千次阅读 2018-09-10 16:52:08
    线程程序中,函数经常使用全局变量或静态变量,这是不会影响程序的正确性的,但如果线程调用的函数使用全局变量或静态变量,则很可能引起错误。因为这些函数使用的全局变量和静态变量无法为不同的线程保存各自的...
  • 线程间的数据传递主要分为向线程传递...调用start方法之前通过线程类的构造方法将数据传入线程。 public class MyThread extends Thread { private String name; public MyThread1(String name) { this.nam...
  • linux线程私有数据详解

    千次阅读 2016-08-22 22:07:00
    线程程序中,函数经常使用全局变量或静态变量,这是不会影响程序的正确性的,但如果线程调用的函数使用全局变量或静态变量,则很可能引起编程错误,因为这些函数使用的全局变量和静态变量无法为不同的线程保存各自的...
  • qt udp多线程收发数据

    2018-04-08 16:37:17
    基于多线程的QUdpSocket收发数据程序,界面上可以输入目标ip、port,与网络调试助手调试ok 欢迎下载,并指出程序中的问题,谢谢
  • Linux系统编程——线程私有数据

    万次阅读 2015-06-11 14:36:30
    线程程序中,经常要用全局变量来实现多个函数间的数据共享。由于数据空间是共享的,因此全局变量也为所有线程共有。 但有时应用程序设计中必要提供线程私有的全局变量,这个变量仅在线程中有效,但却可以跨过多...
  • 线程程序中,我们经常要用到"全局变量"以实现多个函数间共享数据, 然而线程环境下,由于数据空间是共享的,因此全局变量也为所有线程所共有。但有时应用程序设计中有必要提供线程私有的全局变量,仅某个...
  • C语言中多线程数据共享问题

    千次阅读 2019-04-20 14:39:20
    C语言中多线程之间共享全局变量data段数据实例(和多进程之间相反,多进程之间的全局变量不共享,每一个进程有独自的0到4G的地址空间) 2 #include <string.h> 3 #include <unistd.h> 4 #include &...
  • 线程分批处理数据

    千次阅读 2019-06-05 17:17:06
    需求: 目前蚂蚁课堂有10万个用户,现在蚂蚁课堂需要做活动,给每一个用户发送一条...3.计算每个线程需要分批跑的数据 4.进行分批发送 实例: 实体类: package com.emple.entity; import java.security.SecureRa...
  • 线程计算数据,然后合并数据

    千次阅读 2014-09-22 19:19:32
    线程计算数据,然后合并数据
  • C++多线程处理数据

    千次阅读 2016-12-29 15:13:41
    背景服务器处理大规模的数据中,使用单线程处理数据,对多核CPU简直是暴殄天物,除非特定情况如单核单线程测试算法运行时间。 处理任务:处理将近5000个视频的特征 处理目标:充分利用CPU核,多线程
  • 线程数据采集器源码(C# )

    热门讨论 2010-04-05 16:37:09
    线程数据采集器源码(C# ) 多线程数据采集器源码(C# ) 多线程数据采集器源码(C# ) 多线程数据采集器源码(C# ) 多线程数据采集器源码(C# )
  • Java多线程编程---线程数据共享

    千次阅读 2018-04-08 09:19:07
    线程范围内共享数据 线程范围内共享变量要实现的效果为:多个对象间共享同一线程内的变量。未实现线程共享变量的demo:public class ThreadScopeDataShare { private static int data = 0; public static void ...
  • 线程与私有数据

    千次阅读 2011-02-13 10:13:00
    转载自:... <br />比如程序里可能需要每个线程维护一个链表,而会使用相同的函数来操作这个链表,最简单的方法就是使用同名而不同变量地址的线程相关数据结构。这样
  • Java多线程---从线程中返回数据

    万次阅读 多人点赞 2016-05-12 12:26:04
    线程中返回数据 Callable接口获得线程的返回值 通过回调函数返回数据
  • Java多线程数据隔离(ThreadLocal)

    千次阅读 2016-11-24 14:33:39
    变量值的共享可以使用public static变量的形式,所有的线程都...这里的线程A和B共用一个静态变量t1,但是两个线程的变量数据互不干扰。说明每个线程都有属于自己的私有数据。无论是子线程还是父线程数据都是隔离的。

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,737,449
精华内容 694,979
关键字:

线程的数据在哪