`
xiaofan_0204
  • 浏览: 126632 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

线程范围内的共享变量(一)

    博客分类:
  • Java
 
阅读更多
关于线程范围内的变量共享,这种应用场景,在实际开发中应用不是很多,但对理解和加深多线程编程却有很大的好处!这里在网上找了一些资料,收藏仅供以后学习:
创建两个个线程,他们都访问同一个变量,要求同一个线程设置的值只能被自身所获取!

package com.datashare;

import java.util.Random;

public class ThreadDataShare {
	public static int data = 0;
	
	public static void main(String[] args) throws Exception {
		for (int i = 0; i < 2; i++) {
			new Thread(new Runnable() {

				@Override
				public void run() {
					data = new Random().nextInt();
					System.out.println(Thread.currentThread().getName()
							+ " has put data :" + data);
					new A().get();
					new B().get();
				}
			}).start();
		}
	}

	static class A {
		public void get() {
			System.out.println("A from " + Thread.currentThread().getName()
					+ " get data : " + data);
		}
	}

	static class B {
		public void get() {
			System.out.println("A from " + Thread.currentThread().getName()
					+ " get data : " + data);
		}
	}
}


运行结果如下:
Thread-0 has put data :1118128123
Thread-1 has put data :1118128167
A from Thread-1 get data : 1118128167
A from Thread-0 get data : 1118128167
B from Thread-1 get data : 1118128167
B from Thread-0 get data : 1118128167

从结果中可以看出Thread-0该线程设置的值并没有被与该线程相关的类读取到!这使什么原因呢,这是因为,线程Thread-0刚把data设置值之后,还没来得及输出该值就被下个线程给改变了!所以线程一读取不到它自己设置的值!有可能甚至会出现Thread-0 has put data 和 Thread-1 has put data输出值相等的情况。

那怎么解决这种情况呢,办法有很多种:
其一:
package com.datashare;

import java.util.Random;

public class ThreadDataShare {
	public static int data = 0;

	public static void main(String[] args) throws Exception {
		for (int i = 0; i < 2; i++) {
			[b]Thread.sleep(100);[/b]			new Thread(new Runnable() {

				@Override
				public void run() {
					data = new Random().nextInt();
					System.out.println(Thread.currentThread().getName()
							+ " has put data :" + data);
					new A().get();
					new B().get();
				}
			}).start();
		}
	}

	static class A {
		public void get() {
			System.out.println("A from " + Thread.currentThread().getName()
					+ " get data : " + data);
		}
	}

	static class B {
		public void get() {
			System.out.println("B from " + Thread.currentThread().getName()
					+ " get data : " + data);
		}
	}
}


粗体代码就是延长下个线程的创建时间,但是这样并不能解决根本问题!

方法二:
package com.datashare;

import java.util.HashMap;
import java.util.Map;
import java.util.Random;

public class ThreadDataShare {
	public static int data = 0;

	private static Map<Thread, Integer> map = new HashMap<Thread, Integer>();
	public static void main(String[] args) throws Exception {
		for (int i = 0; i < 2; i++) {
			new Thread(new Runnable() {

				@Override
				public void run() {
					[b]int data = new Random().nextInt();[/b]					map.put(Thread.currentThread(), data);
					System.out.println(Thread.currentThread().getName()
							+ " has put data :" + data);
					
					new A().get();
					new B().get();
				}
			}).start();
		}
	}

	static class A {
		public void get() {
			System.out.println("A from " + Thread.currentThread().getName()
					+ " get data : " + map.get(Thread.currentThread()));
		}
	}

	static class B {
		public void get() {
			System.out.println("B from " + Thread.currentThread().getName()
					+ " get data : " + map.get(Thread.currentThread()));
		}
	}
}

其上实例是线程范围内变量共享的真实写照,上代码逻辑并不能于理解,需要注意的是data不是定义成了类变量了嘛,干嘛还要在此用一个方法的成员变量来覆盖!首先还得回到第一个实例,因为如果定义成类变量会出现第一个线程刚设置值马上又被第二个线程覆盖这种情况,所以才在方法里定义成方法的局部变量,每条线程会为各自的run方法分配各自的存储空间用于存储各自方法内部的局部变量,当这个方法结束时,分配给这个方法的栈就会被释放,栈中变量也会消失!而且很大程度上节省了内存!
分享到:
评论
1 楼 bugwolf 2012-12-02  
请问在方法二中,使用的是在方法run中定义的int data,那么实际上这个变量已经就不是类A和类B的共享变量,而成了run方法的私有变量,怎么能体现“线程间共享变量”的这个说法呢?

相关推荐

    Java多线程编程之ThreadLocal线程范围内的共享变量

    Java中的ThreadLocal是一种特殊类型的变量,它主要用于在多线程环境下提供线程范围内的局部变量。每个线程都拥有自己独立的ThreadLocal变量副本,互不影响。这与传统的全局变量不同,全局变量在所有线程间共享,可能...

    易语言线程中的变量应用

    1. **全局变量**:全局变量在整个程序范围内可见,包括所有线程。当一个线程修改全局变量时,其他线程也可以立即看到这个变化。然而,由于多线程可能导致并发访问同一变量,因此需要考虑同步机制,如使用“锁定资源...

    Java多线程与并发库高级应用视频教程22集

    【】01传统线程技术回顾【】02传统定时器技术回顾【】03传统线程互斥技术【】04传统线程同步通信技术【】04传统线程同步通信技术_分割纪录【】05线程范围内共享变量的概念与作用【】06ThreadLocal类及应用技巧【】06...

    线程并发时 本地变量和Lock锁的效率比较

    本地变量,也称为线程局部变量,为每个线程提供了一个独立的变量副本。这意味着每个线程都拥有自己的变量实例,不会与其他线程共享,从而避免了数据竞争的问题。在Java中,可以使用`ThreadLocal`类来创建线程本地...

    python 多线程共享全局变量的优劣

    全局变量是在程序的全局范围内定义的变量,可以在程序的任何地方被访问。而在Python中,多线程是指在单个进程中同时执行多个线程,每个线程可以独立地执行任务。 **一、多线程共享全局变量的原理** 在Python中,多...

    张孝祥Java多线程与并发库高级应用笔记

    - **概念**:线程范围内共享变量是指在线程间共享的数据,需小心处理以避免竞态条件和数据不一致性。 - **作用**:允许线程间通信和协作,但需采用适当的同步机制(如`synchronized`关键字、`Lock`接口)以确保数据...

    java 猜数字游戏,学习线程

    - 随机数生成线程:使用`Random`类生成一个指定范围内的随机整数,并将其存储在一个全局变量中,如`volatile`修饰的`int`类型变量,以确保线程可见性。 - 猜测线程:不断接收用户输入,与随机数进行比较,判断是否...

    JDK5中的多线程并发库

    5. **线程范围内共享数据**: - **应用场景**:比如银行转账,转入和转出需要共享数据。 - **解决方案**:可以使用自定义`Map`以`Thread`对象为Key保存数据,或者使用`ThreadLocal`,它为每个线程维护独立的变量...

    MFC线程间通信

    全局变量在整个程序范围内都是可见的,因此不同线程可以访问同一全局变量来交换数据。这种方式最简单,但也是最不安全的,因为如果没有适当的同步机制,多个线程同时读写全局变量可能导致数据不一致或者死锁。为了...

    Posix线程编程指南

    这些函数包括获取本线程ID的pthread_self()函数,判断两个线程是否为同一个线程的pthread_equal()函数,确保某些操作只被执行一次的pthread_once()函数,以及用于强制结束其他线程的pthread_kill_other_threads_np()...

    多线程并发编程-同步与互斥-原⼦变量-并发和⽆锁 数据结构

    在线程的共享资源中,全局变量是在程序的全局范围内定义的变量,堆用于存储线程创建的对象等信息,除此之外,所有线程共享同一块代码段。 5.2 线程⽣命周期 线程的生命周期涵盖了从其创建、执行、到终止的所有阶段...

    Java多线程与线程安全实践-基于Http协议的断点续传

    在实现断点续传时,每个线程可能负责下载文件的一个部分,通过共享变量(如`AtomicInteger`)记录当前的下载进度,并确保线程安全。 线程安全是多线程编程中的一个重要概念,指的是在多线程环境下,一个类或者对象...

    Windows多线程编程详解

    TLS允许每个线程拥有自己的数据副本,即使这些数据在全局范围内声明。这对于需要在多个线程间区分状态的情况非常有用。 总结,Windows多线程编程涉及的内容广泛,从线程创建、同步、通信到线程管理,都需要开发者...

    经典Java多线程与并发库高级应用

    除了上述提到的技术点,本教程还会涉及到ThreadLocal类、线程范围内共享变量、多个线程之间共享数据的方式、java5原子性操作类的应用、Callable与Future的应用、线程锁技术、读写锁技术等内容。这些技术点都旨在帮助...

    java线程:两种传统的实现方式.zip

    在这个例子中,每个`CountingThread`实例负责计算特定范围内的数字之和,并将结果累加到全局变量`globalSum`上。由于多线程环境下对共享资源的访问可能引发竞态条件,我们使用`synchronized`关键字确保了对`...

    JDK5中的多线程并发库.doc

    5. **线程范围内共享数据** - **应用场景**:如银行转账,需要在同一线程内共享数据以保证事务的正确性。 - **解决方案**:可以使用自定义`Map`,Key为`Thread`类型,Value为共享数据,或者利用`ThreadLocal`,每...

    Java多线程编程总结

    - 线程总是隶属于某个进程,同一进程内的多个线程共享内存空间。 2. **Java中的线程** - 在Java中,“线程”有两层含义: - `java.lang.Thread` 类的一个实例。 - 线程的执行过程。 - 使用 `java.lang.Thread`...

Global site tag (gtag.js) - Google Analytics