public class Person {
public String name;
public int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
}
public class MainActivity extends Activity {
//ThreadLocal初始化
private ThreadLocal<Person> mThreadLocal = new ThreadLocal<Person>();
private Person mPerson = new Person("王大侠", 100);
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//将mPerson对象设置进去
mThreadLocal.set(mPerson);
Log.d("主线程", " 名字:" + mThreadLocal.get().name + " 年龄:" + mThreadLocal.get().age);
}
}
public class MainActivity extends Activity {
//ThreadLocal初始化
private ThreadLocal<Person> mThreadLocal = new ThreadLocal<Person>();
private Person mPerson = new Person("王大侠", 100);
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//将mPerson对象设置进去
mThreadLocal.set(mPerson);
new Thread(new Runnable() {
@Override
public void run() {
Log.d("子线程", " 名字:" + mThreadLocal.get().name + " 年龄:" + mThreadLocal.get().age);
}
}).start();
}
}
`java.lang.NullPointerException: Attempt to read from field ' java.lang.String com.example.franky.myapplication.Person.name' on a null object reference`
/**
* Creates a new thread-local variable.
*/
public ThreadLocal() {}
implements a thread-local storage, that is,
a variable for which each thread * has its own value.
all threads share the same {@code threadlocal} object,
* but each sees a different value when accessing it, and
changes made by one * thread do not affect the other threads.
the implementation supports * {@code null} values.
public class ThreadLocal<T> {
}
public void set(T value) {
Thread currentThread = Thread.currentThread();
Values values = values(currentThread);
if (values == null) {
values = initializeValues(currentThread);
}
values.put(this, value);
}
Values values(Thread current) {
return current.localValues;
}
values initializevalues(thread current) { return current.localvalues = new values();}
Values() {
initializeTable(INITIAL_SIZE);
this.size = 0;
this.tombstones = 0;
}
private void initializeTable(int capacity) {
this.table = new Object[capacity * 2];
this.mask = table.length - 1;
this.clean = 0;
this.maximumLoad = capacity * 2 / 3; // 2/3
}
/** * Map entries. Contains alternating keys (ThreadLocal) and values. * The length is always a power of 2. */ private Object[] table;
/** Used to turn hashes into indices. */ private int mask; /** Number of live entries. */ private int size; /** Number of tombstones. */ private int tombstones; /** Maximum number of live entries and tombstones. */ private int maximumLoad; /** Points to the next cell to clean up. */ private int clean;
values.put(this, value);
/**
* Sets entry for given ThreadLocal to given value, creating an
* entry if necessary.
*/
void put(ThreadLocal<?> key, Object value) {
cleanUp();
// Keep track of first tombstone. That's where we want to go back
// and add an entry if necessary.
int firstTombstone = -1;
for (int index = key.hash & mask;; index = next(index)) {
Object k = table[index];
if (k == key.reference) {
// Replace existing entry.
table[index + 1] = value;
return;
}
if (k == null) {
if (firstTombstone == -1) {
// Fill in null slot.
table[index] = key.reference;
table[index + 1] = value;
size++;
return;
}
// Go back and replace first tombstone.
table[firstTombstone] = key.reference;
table[firstTombstone + 1] = value;
tombstones--;
size++;
return;
}
// Remember first tombstone.
if (firstTombstone == -1 && k == TOMBSTONE) {
firstTombstone = index;
}
}
}
private static AtomicInteger hashCounter = new AtomicInteger(0); private final int hash = hashCounter.getAndAdd(0x61c88647 * 2);
if (firstTombstone == -1) {
// Fill in null slot.
table[index] = key.reference;
table[index + 1] = value;
size++;
return;
}
public T get() {
// Optimized for the fast path.
Thread currentThread = Thread.currentThread();
Values values = values(currentThread);
if (values != null) {
Object[] table = values.table;
int index = hash & values.mask;
if (this.reference == table[index]) {
return (T) table[index + 1];
}
} else {
values = initializeValues(currentThread);
}
return (T) values.getAfterMiss(this);
}
Object value = key.initialValue();
protected T initialValue() {
return null;
}
public class MainActivity extends Activity {
private InheritableThreadLocal<Person> mInheritableThreadLocal = new InheritableThreadLocal<Person>();
private Person mPerson = new Person("王大侠", 100);
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//将mPerson设置到当前线程
mInheritableThreadLocal.set(mPerson);
Log.d("主线程"+Thread.currentThread().getName(), " 名字:" + mInheritableThreadLocal.get().name + " 年龄:" + mInheritableThreadLocal.get().age);
new Thread(new Runnable() {
@Override
public void run() {
Log.d("子线程"+Thread.currentThread().getName(), " 名字:" + mInheritableThreadLocal.get().name + " 年龄:" + mInheritableThreadLocal.get().age);
}
}).start();
}}
04-21 13:09:11.046 19457-19457/com.example.franky.myapplication D/主线程main: 名字:王大侠 年龄:100 04-21 13:09:11.083 19457-21729/com.example.franky.myapplication D/子线程Thread-184: 名字:王大侠 年龄:100
public class InheritableThreadLocal<T> extends ThreadLocal<T> {
/**
* Creates a new inheritable thread-local variable.
*/
public InheritableThreadLocal() {
}
/**
* Computes the initial value of this thread-local variable for the child
* thread given the parent thread's value. Called from the parent thread when
* creating a child thread. The default implementation returns the parent
* thread's value.
*
* @param parentValue the value of the variable in the parent thread.
* @return the initial value of the variable for the child thread.
*/
protected T childValue(T parentValue) {
return parentValue;
}
@Override
Values values(Thread current) {
return current.inheritableValues;
}
@Override
Values initializeValues(Thread current) {
return current.inheritableValues = new Values();
}
}
private void create(ThreadGroup group, Runnable runnable, String threadName, long stackSize) {
...
// Transfer over InheritableThreadLocals.
if (currentThread.inheritableValues != null) {
inheritableValues = new ThreadLocal.Values(currentThread.inheritableValues);
}
// add ourselves to our ThreadGroup of choice
this.group.addThread(this);
}
/**
* Used for InheritableThreadLocals.
*/
Values(Values fromParent) {
this.table = fromParent.table.clone();
this.mask = fromParent.mask;
this.size = fromParent.size;
this.tombstones = fromParent.tombstones;
this.maximumLoad = fromParent.maximumLoad;
this.clean = fromParent.clean;
inheritValues(fromParent);
}
机械节能产品生产企业官网模板...
大气智能家居家具装修装饰类企业通用网站模板...
礼品公司网站模板
宽屏简约大气婚纱摄影影楼模板...
蓝白WAP手机综合医院类整站源码(独立后台)...苏ICP备2024110244号-2 苏公网安备32050702011978号 增值电信业务经营许可证编号:苏B2-20251499 | Copyright 2018 - 2025 源码网商城 (www.ymwmall.com) 版权所有