`
aty
  • 浏览: 35534 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

JDK的ThreadLocal理解(一)使用和测试

阅读更多

       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,的确以一种很优雅的方式解决了线程安全问题。

 

 

 

  

2
1
分享到:
评论
1 楼 zh_harry 2013-07-25  
ThreadLocal独家解秘 附JDK源码
http://lizhizhang.iteye.com/blog/1909765

相关推荐

Global site tag (gtag.js) - Google Analytics