多线程篇四:ThreadLocal实现线程范围内变量共享
1.static实现线程范围内变量共享
package com.test.shareData; import java.util.Random; /**
* 多线程范围内的数据共享
* @author Administrator
*
*/
public class ThreadScopeShareData { private static int data;
public static void main(String[] args) {
for(int i=0;i<2;i++){
new Thread(new Runnable(){
@Override
public void run() {
data=new Random().nextInt();
System.out.println("currentThread:"+Thread.currentThread().getName()+" get data value is:"+data);
new A().get();
new B().get();
/**
* 输出:static 变量是内存中共享的,第二个线程的值会覆盖第一个线程的值
* currentThread:Thread-0 get data value is:312589459
currentThread:Thread-1 get data value is:312589459
A currentThread:Thread-1 get data value is:312589459
A currentThread:Thread-0 get data value is:312589459
B currentThread:Thread-1 get data value is:312589459
B currentThread:Thread-0 get data value is:312589459
*/
}
}).start();
} } static class A{
public void get(){
System.out.println("A currentThread:"+Thread.currentThread().getName()+" get data value is:"+data);
}
} static class B{
public void get(){
System.out.println("B currentThread:"+Thread.currentThread().getName()+" get data value is:"+data);
}
}
}
currentThread:Thread-0 get data value is:312589459
currentThread:Thread-1 get data value is:312589459
A currentThread:Thread-1 get data value is:312589459
A currentThread:Thread-0 get data value is:312589459
B currentThread:Thread-1 get data value is:312589459
B currentThread:Thread-0 get data value is:312589459
package com.test.shareData; import java.util.Random; /***
* @description 通过ThreadLocal实现,同一个线程范围内,不同的对象中数据共享
* 注意:一个ThradLocal只能代表一个变量,即只能放一个数据;多个线程范围内都需要共享数据,则需要定义多个ThreadLocal
* 另外:多个变量共享,同一个线程范围内共享,可通过创建实体对象,将实体对象放到ThreadLocal中
*
*/
public class ThreadLocalTest1 { 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();
x.set(data);
System.out.println(Thread.currentThread().getName()+" data"+data);
MyTreadScopeData1 myTreadScopeData =MyTreadScopeData1.getInstance();
myTreadScopeData.setName("chenxiaobing"+data);
myTreadScopeData.setAge(data);
new A().get();
new B().get();
}
}).start();
} }
static class A{
int data=x.get();
private void get(){
System.out.println("class A:"+Thread.currentThread().getName()+data);
MyTreadScopeData1 myTreadScopeData =MyTreadScopeData1.getInstance();
System.out.println("class A myThreadLocal:"+Thread.currentThread().getName()+myTreadScopeData.getName());
}
} static class B{
int data=x.get();
private void get(){
System.out.println("class B:"+Thread.currentThread().getName()+data);
MyTreadScopeData1 myTreadScopeData =MyTreadScopeData1.getInstance();
System.out.println("class B myThreadLocal:"+Thread.currentThread().getName()+myTreadScopeData.getName());
}
}
} class MyTreadScopeData1{ private MyTreadScopeData1(){}//私有的构成方法,使其他无法创建实例对象 //1.懒汉、饱汉模式的单例,预先定义一个静态的实例对象
/*private static MyTreadScopeData1 instance=new MyTreadScopeData1();
public static MyTreadScopeData1 getInstance(){//定义一个可供其他调用的静态方法
return instance;
}*/ //2.饿汉模式的单例,只有在需要时才创建实例对象
/*private static MyTreadScopeData1 instance=null;
public static synchronized MyTreadScopeData1 getInstance(){//定义一个可供其他调用的静态方法
if(null==instance){
instance =new MyTreadScopeData1();
}
return instance;
}*/ //3.这里ThreadLocal的使用,类似1/2中的单例模式,只是1/2单例模式,所有线程都会共享MyTreadScopeData1的实例对象
private static ThreadLocal<MyTreadScopeData1> myThreadLocal=new ThreadLocal<MyTreadScopeData1>(); //不同的线程共享不同的实例对象,不需要使用synchronized
public static MyTreadScopeData1 getInstance(){
MyTreadScopeData1 instance=myThreadLocal.get();
if(null==instance){
instance =new MyTreadScopeData1();
myThreadLocal.set(instance);
}
return instance;
} 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;
} }
输出:
currentThread:Thread-1 get data value is:139815514
A currentThread:Thread-1 get map:139815514
currentThread:Thread-0 get data value is:-1291672817
A currentThread:Thread-0 get map:-1291672817
B currentThread:Thread-1 get map:139815514
B currentThread:Thread-0 get map:-1291672817
2.ThreadLocal实现线程范围内变量共享
package com.test.shareData; import java.util.Random; /***
* @description 通过ThreadLocal实现,同一个线程范围内,不同的对象中数据共享
* 注意:一个ThradLocal只能代表一个变量,即只能放一个数据;多个线程范围内都需要共享数据,则需要定义多个ThreadLocal
* 另外:多个变量共享,同一个线程范围内共享,可通过创建实体对象,将实体对象放到ThreadLocal中
*
*/
public class ThreadLocalTest { //1.一个ThradLocal只能代表一个变量,即只能放一个数据;多个线程范围内都需要共享数据,则需要定义多个ThreadLocal
private static ThreadLocal<Integer> x=new ThreadLocal<Integer>(); //2.多个变量共享(共享name,age),同一个线程范围内共享,可通过创建实体对象,将实体对象放到ThreadLocal中
private static ThreadLocal<MyTreadScopeData> myThreadLocal=new ThreadLocal<MyTreadScopeData>();
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();
x.set(data);
System.out.println(Thread.currentThread().getName()+" data"+data);
MyTreadScopeData myTreadScopeData=new MyTreadScopeData();
myTreadScopeData.setName("chenxiaobing");
myTreadScopeData.setAge(28);
myThreadLocal.set(myTreadScopeData);
new A().get();
new B().get();
}
}).start();
} }
static class A{
int data=x.get();
private void get(){
System.out.println("class A:"+Thread.currentThread().getName()+data);
// MyTreadScopeData myThread=myThreadLocal.get();
// myThread.setAge(30);
// myThread.setName("aaaaaaaaaaaaaaa");
System.out.println("class A myThreadLocal:"+Thread.currentThread().getName()+myThreadLocal.get().getName());
}
} static class B{
int data=x.get();
private void get(){
System.out.println("class B:"+Thread.currentThread().getName()+data);
// MyTreadScopeData myThread=myThreadLocal.get();
// myThread.setAge(30);
// myThread.setName("bbbbbbbbbbbbbbbb");
System.out.println("class B myThreadLocal:"+Thread.currentThread().getName()+myThreadLocal.get().getName()); }
}
} class MyTreadScopeData{
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 data1679550355
Thread-1 data387829581
class A:Thread-1387829581
class A myThreadLocal:Thread-1chenxiaobing
class B:Thread-1387829581
class B myThreadLocal:Thread-1chenxiaobing
class A:Thread-01679550355
class A myThreadLocal:Thread-0chenxiaobing
class B:Thread-01679550355
class B myThreadLocal:Thread-0chenxiaobing
单例模式:
package com.test.shareData; import java.util.Random; /***
* @description 通过ThreadLocal实现,同一个线程范围内,不同的对象中数据共享
* 注意:一个ThradLocal只能代表一个变量,即只能放一个数据;多个线程范围内都需要共享数据,则需要定义多个ThreadLocal
* 另外:多个变量共享,同一个线程范围内共享,可通过创建实体对象,将实体对象放到ThreadLocal中
*
*/
public class ThreadLocalTest1 { 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();
x.set(data);
System.out.println(Thread.currentThread().getName()+" data"+data);
MyTreadScopeData1 myTreadScopeData =MyTreadScopeData1.getInstance();
myTreadScopeData.setName("chenxiaobing"+data);
myTreadScopeData.setAge(data);
new A().get();
new B().get();
}
}).start();
} }
static class A{
int data=x.get();
private void get(){
System.out.println("class A:"+Thread.currentThread().getName()+data);
MyTreadScopeData1 myTreadScopeData =MyTreadScopeData1.getInstance();
System.out.println("class A myThreadLocal:"+Thread.currentThread().getName()+myTreadScopeData.getName());
}
} static class B{
int data=x.get();
private void get(){
System.out.println("class B:"+Thread.currentThread().getName()+data);
MyTreadScopeData1 myTreadScopeData =MyTreadScopeData1.getInstance();
System.out.println("class B myThreadLocal:"+Thread.currentThread().getName()+myTreadScopeData.getName());
}
}
} class MyTreadScopeData1{ private MyTreadScopeData1(){}//私有的构成方法,使其他无法创建实例对象 //1.懒汉、饱汉模式的单例,预先定义一个静态的实例对象
/*private static MyTreadScopeData1 instance=new MyTreadScopeData1();
public static MyTreadScopeData1 getInstance(){//定义一个可供其他调用的静态方法
return instance;
}*/ //2.饿汉模式的单例,只有在需要时才创建实例对象
/*private static MyTreadScopeData1 instance=null;
public static synchronized MyTreadScopeData1 getInstance(){//定义一个可供其他调用的静态方法
if(null==instance){
instance =new MyTreadScopeData1();
}
return instance;
}*/ //3.这里ThreadLocal的使用,类似1/2中的单例模式,只是1/2单例模式,所有线程都会共享MyTreadScopeData1的实例对象
private static ThreadLocal<MyTreadScopeData1> myThreadLocal=new ThreadLocal<MyTreadScopeData1>(); //不同的线程共享不同的实例对象,不需要使用synchronized
public static MyTreadScopeData1 getInstance(){
MyTreadScopeData1 instance=myThreadLocal.get();
if(null==instance){
instance =new MyTreadScopeData1();
myThreadLocal.set(instance);
}
return instance;
} 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 data667513514
class A:Thread-0667513514
class A myThreadLocal:Thread-0chenxiaobing667513514
Thread-1 data-452485471
class A:Thread-1-452485471
class A myThreadLocal:Thread-1chenxiaobing-452485471
class B:Thread-0667513514
class B:Thread-1-452485471
class B myThreadLocal:Thread-1chenxiaobing-452485471
class B myThreadLocal:Thread-0chenxiaobing667513514
多线程篇四:ThreadLocal实现线程范围内变量共享的更多相关文章
- 多线程(四) 实现线程范围内模块之间共享数据及线程间数据独立(Map集合)
多个线程访问共享对象和数据的方式 1.如果每个线程执行的代码相同,可以使用同一个Runnable对象,这个Runnable对象中有那个共享数据,例如,买票系统就可以这么做. 2.如果每个线程执行的代码 ...
- 多线程(三) 实现线程范围内模块之间共享数据及线程间数据独立(ThreadLocal)
ThreadLocal为解决多线程程序的并发问题提供了一种新的思路.JDK 1.2的版本中就提供java.lang.ThreadLocal,使用这个工具类可以很简洁地编写出优美的多线程程序,Threa ...
- ThreadLocal实现线程范围内共享
线程范围内共享,即是对相同一段代码,在不同的模块调用时使用一份数据,而在另外一个线程中又使用另外一份数据. ThreadLocal使用set方法为一个新的线程增加一条记录,key是各自的线程,valu ...
- 线程:ThreadLocal实现线程范围内共享变量
在web应用中,一个请求(带有请求参数)就是一个线程,那么如何区分哪些参数属于哪个线程呢?比如struts中,A用户登录,B用户也登录,那么在Action中怎么区分哪个是A用户的数据,哪个是B用户的数 ...
- 线程系列4--Java线程范围内的共享数据(一)
这张图片是我看传智播客的视频时的截屏,这个图片很直观的展示了线程范围内的数据共享.当同一个线程在执行三个不同业务模块时,这三个业务模块访问的数据是共享的.更直白的说,当一个执行线索在穿个每个业务模块时 ...
- java多线程与线程并发四:线程范围内的共享数据
当多个线程操作同一个共有数据时,一个线程对共有数据的改变会影响到另一个线程.比如下面这个例子:两个线程调用同一个对象的的方法,一个线程的执行结果会影响另一个线程. package com.sky.th ...
- (Java多线程系列四)停止线程
停止线程 停止线程的思路 ①使用退出标志,使线程正常退出,也就是当run()方法结束后线程终止. class Thread01 extends Thread { // volatile关键字解决线程的 ...
- 【Java多线程系列四】控制线程执行顺序
假设有线程1/线程2/线程3,线程3必须在线程1/线程2执行完成之后开始执行,有两种方式可实现 Thread类的join方法:使宿主线程阻塞指定时间或者直到寄生线程执行完毕 CountDownLatc ...
- ThreadLocal实现线程范围的共享变量
一.如何理解线程范围内共享数据 1.static int num=0; 2.线程1访问num变量,并设置为num=2:线程2访问num变量,并设置为num=3: 3.当线程1中对象A.B.C 在访问线 ...
随机推荐
- 【guava】字符串操作
一,Strings类 public void testStrings(){ Strings.isNullOrEmpty("");//返回true Strings.nullToEmp ...
- 你必须知道的----C语言笔试面试中经典易错的一些知识点(持续更新)
1. 关于二级指针的解析和引用 1.1 二级指针意义 二级指针存放的是一级指针的地址 Ex: Int a = ; Int *p = &a; Int **q = &p; 1.2 ...
- ubuntu下的pycharm4中文路径乱码
修改字体: 设置(settings)->外观与行为(appearance & behavior) -> 外观(appearance) ->我选择的主题是Darcula 但其字 ...
- C#基于SQLiteHelper类似SqlHelper类实现存取Sqlite数据库的方法
本文实例讲述了C#基于SQLiteHelper类似SqlHelper类实现存取Sqlite数据库的方法.分享给大家供大家参考.具体如下: 这个类不是我实现的,英文原文地址为http://www.egg ...
- javascript高级程序设计---js事件思维导图
绘制思维软件与平时用的笔记,以及导出功能,这三个问题综合起来,于是我把思维导图分开画 1.js事件的基本概念 2.js事件的事件处理程序 3.js事件的事件对象
- 如何在Qt Creator 创建一个.pri文件
如何在Qt Creator 创建一个.pri文件 2013年10月09日 ⁄ 综合 ⁄ 共 254字 ⁄ 字号 小 中 大 ⁄ 评论关闭 这个问题很少人写,因为比较简单,但是让却让我花了好大功夫才 ...
- 基础问题:设置radio、select、checkbox 的readonly 属性
编辑记录的时候,有时候需要禁止用户修改某些项目,常用的方法有以下两种: 1>设置表单的readonly属性问题:但是readonly属性对radio.select.checkbox这三个表单不起 ...
- python学习之路---day12
生成器和生成器表达式一:生成器 生成器实质上就是迭代器. 三种方式获取生成器: 01:通过生成器函数 02:通过各种推导式实现生成器 03:通过数据的转换也可以获取生成器 eg:普通函数 def fu ...
- C++_友元1-友元类是什么
友元函数:不是类的成员函数,但是能够访问类的私有数据成员. 之前有个矛盾就是规定非成员函数不能直接访问类的私有数据,但是这会儿却可以,但那只是针对常规非成员函数而言,特殊的非成员函数就可以访问类的私有 ...
- bzoj1934 Vote 善意的投票 最小割(最大匹配)
题目传送门 题目大意:很多小朋友,每个小朋友都有自己的立场,赞成或者反对,如果投了和自己立场不同的票会得到一个能量.又有很多朋友关系,如果一个人和他的一个朋友投的票不同,也会得到一个能量,现在问,通过 ...