多线程篇四: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 在访问线 ...
随机推荐
- python连接postgreSQL
利用python(我用的是python2.7版本)连接postgresql数据库,这里使用psycopg2这个插件 官网下载psycopg2-2.5.1.tar.gz:http://initd.org ...
- 关于hive Metadata 使用 MsSQL
下面的页面里说明, http://docs.hortonworks.com/HDPDocuments/HDP2/HDP-2.0.6.0-Win/bk_installing_hdp_for_window ...
- [SDOi2012]Longge的问题 BZOJ2705 数学
题目背景 SDOi2012 题目描述 Longge的数学成绩非常好,并且他非常乐于挑战高难度的数学问题.现在问题来了:给定一个整数N,你需要求出∑gcd(i, N)(1<=i <=N). ...
- sock文件
无论是mysql,uwsgi还是nginx都会用到sock文件 首先它是由程序自动创建的,并不是我们自己手动.它的作用是用来通信.与之相对应的是tcp socket ,一般的程序会同时支持这两种方式, ...
- alter table添加表约束
翻阅了一下网上关于alter table添加表约束的资料,学习下,然后供自己以后使用. 仅仅供自己使用... 总结alter table ### add constraint ## 使用方法 添加表约 ...
- python 安装 wxPtyhon (window)
检查是否安装pip 打开cmd(全局安装的python)测试是否安装了pip 工具 以上是安装了pip , 执行下载并安装 wxPtyhon 第一种方法: 也可以使用其他的地址 官网地址 https: ...
- bzoj 1189 二分+最大流
题目传送门 思路: 先预处理出每个人到每扇门的时间,用门作为起点进行bfs处理. 然后二分时间,假设时间为x,将每扇门拆成1到x,x个时间点,表示这扇门有几个时间点是可以出去的.对于一扇门,每个时间点 ...
- C# 关于utf-8的研究
前提 如果一不小心把字符转成utf8的格式,但是却产生了乱码.这个时候要么就是寻找其他的转码方式,要么就不想要了,直接过滤吧. 这里说的是直接过滤的办法. 参考链接 https://netvignet ...
- Scala 中 for 循环 和 generator 的使用例子
这个例子是,从每个list中,找到age最大的那个node. class Node(vName: String, vAge: Int) { // Entity class var name: Stri ...
- 基于pydpier爬取1药网(转载)
1.商品爬取 #!/usr/bin/env python # -*- encoding: utf-8 -*- # Created on 2019-02-02 08:59:40 # Project: o ...