ThreadLocal是java中轻量级的线程同步解决方法,为了达到线程安全的目的,采用的是空间隔离的方法。使用方式如下:
1、定义2个会被多线程共享的bean,一个使用ThreadLocal,一个不使用任何线程同步措施
package bean;
public interface IShareBean
{
public void get();
public void autoInc();
}
package bean.impl;
import bean.IShareBean;
public class SafeShareBeanImpl implements IShareBean
{
// 创建一个线程局部变量并赋初值
// 该变量是被所有访问SafeShareBeanImpl类的线程共享的,但不存在线程安全问题
private static ThreadLocal<Integer> localCount = new ThreadLocal<Integer>()
{
protected Integer initialValue()
{
return 0;
};
};
public void get()
{
System.out.println(Thread.currentThread().getName()
+ ",after increment:" + localCount.get());
}
public void autoInc()
{
int count = localCount.get();
System.out.println(Thread.currentThread().getName()
+ ",before increment:" + count);
count++;
localCount.set(count);
}
}
package bean.impl;
import bean.IShareBean;
public class UnSafeShareBeanImpl implements IShareBean
{
private int count = 0;
public void get()
{
System.out.println(Thread.currentThread().getName()
+ ",after increment:" + count);
}
public void autoInc()
{
System.out.println(Thread.currentThread().getName()
+ ",before increment:" + count);
count++;
}
}
2、定义一个线程实现类,用来访问共享bean中的方法
package thread;
import bean.IShareBean;
public class ThreadBody implements Runnable
{
private IShareBean bean = null;
public ThreadBody(IShareBean bean)
{
this.bean = bean;
}
@Override
public void run()
{
bean.autoInc();
try
{
Thread.sleep(1000);
} catch (InterruptedException e)
{
e.printStackTrace();
}
bean.get();
}
}
3、测试线程安全
import thread.ThreadBody;
import bean.IShareBean;
import bean.impl.SafeShareBeanImpl;
import bean.impl.UnSafeShareBeanImpl;
public class Client {
public static void main(String[] args)
{
//会被线程共享的对象
IShareBean unsafe = new UnSafeShareBeanImpl();
IShareBean safe = new SafeShareBeanImpl();
// 线程1和2,共享unsafe
Thread one = buildThread("unsafe-thread-1", unsafe);
Thread two = buildThread("unsafe-thread-2", unsafe);
// 线程安全3和4,共享safe
Thread three = buildThread("safe-thread-1", safe);
Thread four = buildThread("safe-thread-2", safe);
three.start();
four.start();
one.start();
two.start();
}
public static Thread buildThread(String name, IShareBean bean) {
ThreadBody body = new ThreadBody(bean);
Thread thread = new Thread(body);
thread.setName(name);
return thread;
}
}
运行以上代码可以发现,使用ThreadLocal,的确以一种很优雅的方式解决了线程安全问题。