//有问题,打印的数据不对
public class ThreadShareData1 {
private static int data = 0;
static class A{
public void get(){
System.out.println(Thread.currentThread().getName()+" a:"+data);
}
}
static class B{
public void get(){
System.out.println(Thread.currentThread().getName()+" b:"+data);
}
}
public static void main(String[] args) {
for(int i = 0;i<5;i++){
new Thread(new Runnable() {
@Override
public void run() {
data = new Random().nextInt(100);
System.out.println(Thread.currentThread().getName()+" input data :"+data);
new A().get();
new B().get();
}
}).start();
}
}
}
//在某一个线程内,有独立的数据
public class ThreadShareData {
private static Map<Thread,Integer> threadData = new HashMap<Thread,Integer>();
static class A{
public void get(){
int data = threadData.get(Thread.currentThread());
System.out.println(Thread.currentThread().getName()+" a:"+data);
}
}
static class B{
public void get(){
int data = threadData.get(Thread.currentThread());
System.out.println(Thread.currentThread().getName()+" b:"+data);
}
}
public static void main(String[] args) {
for(int i = 0;i<5;i++){
new Thread(new Runnable() {
@Override
public void run() {
int data = new Random().nextInt(100);
System.out.println(Thread.currentThread().getName()+" input data :"+data);
threadData.put(Thread.currentThread(), data);
new A().get();
new B().get();
}
}).start();
}
}
}
//Java提供的类,解决线程数据共享问题
//在某一个线程内,有独立的数据
//总结:一个ThreadLocal只能代表一个变量,所以其中只能放一个数据。如果你有两个变量,只能创建两个ThreadLocal对象。
//也可以把一堆数据封装到一个对象中。
public class ThreadShareData {
//相当于往map中放整数
private static ThreadLocal<Integer> tl = new ThreadLocal<Integer>();
static class A{
public void get(){
int data = tl.get();
System.out.println(Thread.currentThread().getName()+" a:"+data);
}
}
static class B{
public void get(){
int data = tl.get();
System.out.println(Thread.currentThread().getName()+" b:"+data);
}
}
public static void main(String[] args) {
for(int i = 0;i<5;i++){
new Thread(new Runnable() {
@Override
public void run() {
int data = new Random().nextInt(100);
System.out.println(Thread.currentThread().getName()+" input data :"+data);
tl.set(data);
new A().get();
new B().get();
}
}).start();
}
}
}
//在某一个线程内,有独立的数据,封装多个数据
class User{
private int id;
private String name;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
public class ThreadShareData {
//相当于往map中放整数
private static ThreadLocal<User> tl = new ThreadLocal<User>();
static class A{
public void get(){
User user = tl.get();
System.out.println(Thread.currentThread().getName()+" a:"+user.getName());
}
}
static class B{
public void get(){
User user = tl.get();
System.out.println(Thread.currentThread().getName()+" b:"+user.getName());
}
}
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(100);
System.out.println(Thread.currentThread().getName()+" input data :"+data);
User user = new User();
user.setId(data);
user.setName("user"+data);
tl.set(user);
new A().get();
new B().get();
}
}).start();
}
}
}
优美设计
public class Data {
private Data(){}
/**
* 每个线程调用全局的ThreadLocal对象的set方法,就相当于往其内部的map对象中添加一条记录。
* key分别是各自的线程,value是传入的值。
* 在线程结束的时候可以调用ThreadLocal的clear方法,这样可以快速释放内存。不调用也可以,在线程结束的时候自动释放。
* */
private static ThreadLocal<Data> map = new ThreadLocal<Data>();
public static Data getInstance(){//这里不需要synchronized
Data data = map.get();
if(data == null){
data = new Data();
map.set(data);
}
return data;
}
private int id;
private String name;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
public class ThreadShareData {
//相当于往map中放整数
static class A{
public void get(){
System.out.println(Thread.currentThread().getName()+" a:"+Data.getInstance().getId());
}
}
static class B{
public void get(){
System.out.println(Thread.currentThread().getName()+" b:"+Data.getInstance().getId());
}
}
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(100);
System.out.println(Thread.currentThread().getName()+" input data :"+data);
Data.getInstance().setId(data);
new A().get();
new B().get();
}
}).start();
}
}
}
多个线程访问共享对象和数据的方式
可以使用同一个Runnable对象,这样就可以操作同一个数据了