`

多线程课程002:线程范围内的共享变量

 
阅读更多
package cn.itcast.heima2;

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


//单一条线程,这条线程所产生的数据由在这条线程new出来的对象共享
//本题中,线程1产生的数据a,由A对象和B对象使用
//线程2产生的数据b,由A对象和B对象使用
public class ThreadScopeShareData {

//	private static int data = 0;
	private static Map<Thread, Integer> threadData = new HashMap<Thread, Integer>();

	public static void main(String[] args) {
		for (int i = 0; i < 2; i++) {
			new Thread(new Runnable() {
				@Override
				public void run() {
					int data = new Random().nextInt();
					System.out.println(Thread.currentThread().getName()
							+ " has put data :" + data);
					threadData.put(Thread.currentThread(), data);
					new A().get();
					new B().get();
				}
			}).start();
		}
	}

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

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



输出结果:
Thread-0 has put data :806274789
Thread-1 has put data :1710804129
A from Thread-0 get data :806274789
A from Thread-1 get data :1710804129
B from Thread-0 get data :806274789
B from Thread-1 get data :1710804129


下面使用了ThreadLocal类,这个由API提供的类解决了共享变量的思路,其输出结果也如上。

public class ThreadLocalTest {

	private static ThreadLocal<Integer> x = new ThreadLocal<Integer>();
	public static void main(String[] args) {
		for(int i = 0; i < 2; i++){
			new Thread(
					new Runnable(){
						@Override
						public void run() {
							int data = new Random().nextInt();
							System.out.println(Thread.currentThread().getName()
									+ " has put data: " + data);
							x.set(data);
							new A().get();
							new B().get();
						}
						
					}
			).start();
		}
		
	}
	
	static class A{
		public void get(){
			int data = x.get();
			System.out.println("A from" + Thread.currentThread().getName()
					+ " get data: " + data );
		}
	}
	
	static class B{
		public void get(){
			int data = x.get();
			System.out.println("B from" + Thread.currentThread().getName()
					+ " get data: " + data );
		}
	}

}


这个需要学习里边的思想


package cn.itcast.heima2;

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

//	往线程池x里边存入一个整形数据,然后由其他的线程池对象共享使用
//	新的线程存新的数据吗,由其他线程池对象共享使用
//	线程池对象的类的设计,单例的设计,拿到实例,set,拿到实例,get
public class ThreadLocalTest {

	private static ThreadLocal<Integer> x = new ThreadLocal<Integer>();
	private static ThreadLocal<MyThreadScopeData> myThreadScopeData = new ThreadLocal<MyThreadScopeData>();
	public static void main(String[] args) {
		for(int i=0;i<2;i++){
			new Thread(new Runnable(){
				@Override
				public void run() {
					int data = new Random().nextInt();
					System.out.println(Thread.currentThread().getName() 
							+ " has put data :" + data);
					x.set(data);
/*					MyThreadScopeData myData = new MyThreadScopeData();
					myData.setName("name" + data);
					myData.setAge(data);
					myThreadScopeData.set(myData);*/
					MyThreadScopeData.getThreadInstance().setName("name" + data);
					MyThreadScopeData.getThreadInstance().setAge(data);
					new A().get();
					new B().get();
				}
			}).start();
		}
	}
	
	static class A{
		public void get(){
			int data = x.get();
			System.out.println("A from " + Thread.currentThread().getName() 
					+ " get data :" + data);
/*			MyThreadScopeData myData = myThreadScopeData.get();;
			System.out.println("A from " + Thread.currentThread().getName() 
					+ " getMyData: " + myData.getName() + "," +
					myData.getAge());*/
			MyThreadScopeData myData = MyThreadScopeData.getThreadInstance();
			System.out.println("A from " + Thread.currentThread().getName() 
					+ " getMyData: " + myData.getName() + "," +
					myData.getAge());
		}
	}
	
	static class B{
		public void get(){
			int data = x.get();			
			System.out.println("B from " + Thread.currentThread().getName() 
					+ " get data :" + data);
			MyThreadScopeData myData = MyThreadScopeData.getThreadInstance();
			System.out.println("B from " + Thread.currentThread().getName() 
					+ " getMyData: " + myData.getName() + "," +
					myData.getAge());			
		}		
	}
}

class MyThreadScopeData{
	private MyThreadScopeData(){}
	public static /*synchronized*/ MyThreadScopeData getThreadInstance(){
		MyThreadScopeData instance = map.get();
		if(instance == null){
			instance = new MyThreadScopeData();
			map.set(instance);
		}
		return instance;
	}
	//private static MyThreadScopeData instance = null;//new MyThreadScopeData();
	private static ThreadLocal<MyThreadScopeData> map = new ThreadLocal<MyThreadScopeData>();
	
	private String name;
	private int age;
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
}



输出结果如下:
Thread-0 has put data :-1520297586
Thread-1 has put data :-1519143339
A from Thread-1 get data :-1519143339
A from Thread-0 get data :-1520297586
A from Thread-1 getMyData: name-1519143339,-1519143339
A from Thread-0 getMyData: name-1520297586,-1520297586
B from Thread-1 get data :-1519143339
B from Thread-0 get data :-1520297586
B from Thread-1 getMyData: name-1519143339,-1519143339
B from Thread-0 getMyData: name-1520297586,-1520297586

分享到:
评论

相关推荐

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

    主要介绍了Java多线程编程之ThreadLocal线程范围内的共享变量,本文讲解了ThreadLocal的作用和目的、ThreadLocal的应用场景、ThreadLocal的使用实例等,需要的朋友可以参考下

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

    Java多线程与并发库高级应用视频教程22集资源目录:【】01传统线程技术回顾【】02传统定时器技术回顾【】03传统线程互斥技术【】04传统线程同步通信技术【】04传统线程同步通信技术_分割纪录【】05线程范围内共享...

    多线程编程指南PDF

    多线程基础介绍.........................................................................................................................................15 定义多线程术语...................................

    C#线程锁介绍源码

    只有可以被多线程访问的共享资源才需要考虑锁定,比如静态变量,再比如某些缓存中的值,而属于线程内部的变量不需要锁定。 2)多使用lock,少用Mutex 如果你一定要使用锁定,请尽量不要使用内核模块的锁定机制,...

    多线程编程指南(系统描述了线程标准 线程同步 多线程编程原则 等)

    1 多线程基础介绍15 定义多线程术语15 符合多线程标准16 多线程的益处17 提高应用程序的响应 17 有效使用多处理器17 改进程序结构17 占用较少的系统资源17 结合线程和RPC(远程过程调用)18 多线程概念18 并发性和...

    Oracle9i的init.ora参数中文说明

    该参数的值可以是包含在双引号内的任何有效的日期格式掩码。例如: ''MMM/DD/YYYY''。 值范围: 任何有效的日期格式掩码, 但不得超过一个固定长度。 默认值: 派生 nls_timestamp_tz_format: 说明: 与 NLS_TIME_TZ_...

    并行计算导论(原书第2版).[美]Ananth Grama(带详细书签).pdf

    原版自1993年出版第1版到2003年出版第2版以来,已在世界范围内被广泛地采用为高等院校本科生和研究生的教材或参考书。 第1章 并行计算介绍 1.1 推动并行化 1.1.1 计算能力因素——从晶体管到浮点运算速度 1.1.2 ...

    Java并发编程实战

    书中从并发性和线程安全性的基本概念出发,介绍了如何使用类库提供的基本并发构建块,用于避免并发危险、构造线程安全的类及验证线程安全的规则,如何将小的线程安全类组合成更大的线程安全类,如何利用线程来提高...

    谈谈Java中的ThreadLocal

    sysnchronized是一种互斥同步机制,是为了保证在多线程环境下对于共享资源的正确访问。而ThreadLocal从本质上讲,无非是提供了一个“线程级”的变量作用域,它是一种线程封闭(每个线程独享变量)技术,更直白点讲,...

    java面试800题

    volatile:volatile变量表示保证它必须是与主内存保持一致,它实际是""变量的同步"", 也就是说对于volatile变量的操作是原子型的,如用在long 或 double变量前,一般用于多线程编程。 abstract:抽象,必须重载,修饰...

    超级有影响力霸气的Java面试题大全文档

    与cgi的区别在于servlet处于服务器进程中,它通过多线程方式运行其service方法,一个实例可以服务于多个请求,并且其实例一般不会销毁,而CGI对每个请求都产生新的进程,服务完成后就销毁,所以效率上低于servlet。...

    Delphi5开发人员指南

    11.1.2 在Delphi程序中使用多线程 304 11.1.3 关于线程的滥用 305 11.2 TThread对象 305 11.2.1 TThread基础 305 11.2.2 TThread实例 307 11.2.3 线程的终止 307 11.2.4 与VCL同步 308 11.2.5 一个演示程序 310 ...

    java 面试题 总结

    与cgi的区别在于servlet处于服务器进程中,它通过多线程方式运行其service方法,一个实例可以服务于多个请求,并且其实例一般不会销毁,而CGI对每个请求都产生新的进程,服务完成后就销毁,所以效率上低于servlet。...

    Java开发技术大全(500个源代码).

    variableScopeExample.java 变量使用范围示例 第3章 示例描述:本章学习对象和类。 accessMember.java 访问成员变量示例 constructNoPara.java 无参数的构造方法 constructWithPara.java 带参数的构造方法 ...

    Java性能优化

    控制数据共享,在不建立直接关联的条件下,让多个不相关的进程或线程之间实现通信。 2.尽量避免随意使用静态变量 要知道,当某个对象被定义为stataic的变量所引用,那么GC通常是不会回收这个对象所占有的内存,如 ...

    JAVA面试题最全集

    多线程,用什么关键字修饰同步方法?stop()和suspend()方法为何不推荐使用? 59.使用socket建立客户端与服务器的通信的过程 60.JAVA语言国际化应用,Locale类,Unicode 61.描述反射机制的作用 62.如何读写一个...

    oracle数据库经典题目

    系统权限提供了在Oracle数据库系统范围内执行某种任务的操作能力,而对象权限则是一种赋予用户在指定的数据库对象(如表、视图、过程等) 16. Oralce数据库在进行物理备份有联机备份和脱机备份两种方式可供选择。 ...

    操作系统(内存管理)

    所以,如果内存需要非常固定,那么您只需要选择一个内存范围并使用它即可。 不过,即使是在这样一个简单的计算机中,您也会有问题,尤其是当您不知道程序的每个部分将需要多少内存时。如果您的空间有限,而内存...

    mysql数据库my.cnf配置文件

    当主要MySQL线程在一个很短时间内得到非常多的连接请求,这就起作用, # 然后主线程花些时间(尽管很短)检查连接并且启动一个新线程。back_log值指出在MySQL暂时停止回答新请求之前的短时间内多少个请求可以被存在...

Global site tag (gtag.js) - Google Analytics