版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u014252478/article/details/83508905
1、该方法缺点是只能放入一个数据
package 多线程;
import java.util.Random;
//ThreadLocal来完成线程范围内数据的共享
public class pthread {
private static ThreadLocal<Integer> threadLocal = new ThreadLocal<Integer>();
public static void main(String[] args) {
for (int i = 0; i < 2; i++) {
new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
int data = new Random().nextInt();
System.out.println(Thread.currentThread().getName() + " has put a data: " + data);
threadLocal.set(data); //将数据直接扔进去
new TestA().getData();
new TestB().getData();
}
}).start();
}
}
static class TestA {
public void getData() {
System.out.println(" A get data from " + Thread.currentThread().getName() + ":" + threadLocal.get());
}
}
static class TestB {
public void getData() {
System.out.println(" B get data from " + Thread.currentThread().getName() + ":" + threadLocal.get());
}
}
}
2、放入多个数据,如下:
public class ThreadScopeShareData {
//不需要在外面定义threadLocal了,放到User类中了
// private static ThreadLocal<User> threadLocal = new ThreadLocal<User>();
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 a data: " + data);
//这里直接用User去调用getThreadLocal这个静态方法获取本线程范围内的一个User对象
//这里就优雅多了,我完全不用关心如何去拿该线程中的对象,如何把对象放到threadLocal中
//我只要拿就行,而且拿出来的肯定就是当前线程中的对象,原因看下面User类中的设计
User.getThreadInstance().setName("name" + data);
User.getThreadInstance().setAge(data);
new TestA().getData();
new TestB().getData();
}
}).start();
}
}
static class TestA {
public void getData() {
//还是调用这个静态方法拿,因为刚刚已经拿过一次了,threadLocal中已经有了
User user = User.getThreadInstance();
System.out.println("A get data from " + Thread.currentThread().getName() + ": "
+ user.getName() + "," + user.getAge());
}
}
static class TestB {
public void getData() {
User user = User.getThreadInstance();
System.out.println("A get data from " + Thread.currentThread().getName() + ": "
+ user.getName() + "," + user.getAge());
}
}
}
class User {
private User() {}
private static ThreadLocal<User> threadLocal = new ThreadLocal<User>();
//注意,这不是单例,每个线程都可以new,所以不用synchronized,
//但是每个threadLocal中是单例的,因为有了的话就不会再new了
public static /*synchronized*/ User getThreadInstance() {
User instance = threadLocal.get(); //先从当前threadLocal中拿
if(instance == null) {
instance = new User();
threadLocal.set(instance);//如果没有就新new一个放到threadLocal中
}
return instance; //向外返回该User
}
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;
}
}
这个方法可以一次放入多个数据,并且通过类似单例的方式,不需要在将new出来的对象存入threadLocal中。
以上方法是看武哥的文章。
3、在实际项目中,常常会遇到线程内数据共享的问题,我就遇到类似问题:
//privat static int nTimes = entry.getKey();
.........
ScheduledFuture<?> scheduledFuture = pool.scheduleWithFixedDelay(new Runnable()
{
int nTimes = 0;
@Override
public void run() {
nTimes++;
Map jsonMap = JacksonUtil.json2Bean(message, Map.class);
int ChargeLastTime = Integer.parseInt((String) jsonMap.get("EndTime")) - Integer.parseInt((String) jsonMap.get("StartTime")); //充电时长
chargeOrderInfoReqVo.setUserName((String) jsonMap.get("UserName"));
chargeOrderInfoReqVo.setStationID((String) jsonMap.get("StationID")); //运营商自定义唯一编码?
chargeOrderInfoReqVo.setEquipmentID((String) jsonMap.get("EquipmentID")); //运营商设备唯一编码?
chargeOrderInfoReqVo.setConnectorPower(Float.parseFloat((String) jsonMap.get("ConnectorPower")) / 1000);
chargeOrderInfoReqVo.setChargeLast(ChargeLastTime);
chargeOrderInfoReqVo.setMeterValueStart(Float.parseFloat((String) jsonMap.get("MeterValueStart")) / 100);
chargeOrderInfoReqVo.setMeterValueEnd(Float.parseFloat((String) jsonMap.get("MeterValueEnd")) / 100);
LOG.info("------延时------");
try {
Thread.sleep(150000 * nTimes);
}catch (InterruptedException e){
e.printStackTrace();
}
}
}, 10, nTimes * 10, TimeUnit.SECONDS);
我的想法是想要线程每执行一次,就延长一次,同时延长间隔变长,貌似如上好像可以。但在实际过程中,nTimes是一个定值;
意思就是线程类的nTimes * 10并没有变化,这个问题还需要继续研究。。。