论坛首页 Java企业应用论坛

四种方法1秒钟非线程安全类变线程安全类

浏览 5501 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (1) :: 隐藏帖 (0)
作者 正文
   发表时间:2012-06-08   最后修改:2012-06-08

一般来说非线程安全类是有状态的类,就是有属性的类。先看一个非线程安全类的例子:

package info.yiwen.thread.safe;
/**
 * 该类是非线程安全类,因为有一个共享变量state。
 * 
 * 原因:当多个线程使用同一个NotThreadSafe类的一个对象时,
 * 也会共享该对象的state属性,故是非线程安全的。
 * 
 * 也因为该类是非线程安全的,所以该类也不能作为单例对象。
 * 
 * 但是稍加改造也可以成为线程安全的,改造的方法有使用ThreadLocal,使用同步等等
 * 
 * 项目名称:ThreadSafeClass  
 * 类名称:NotThreadSafe  
 * 类描述:暂无
 * 创建人:xueshishasha  
 * 创建时间:2012-6-7 下午09:58:13  
 * 修改备注:
 * @version
 */
public class NotThreadSafe {
	private boolean state;

	public boolean checkState() {
		return isState();
	}
	
	public boolean isState() {
		return state;
	}

	public void setState(boolean state) {
		this.state = state;
	}
}



下面就稍加改造变成线程安全类:
方法1:使用ThreadLocal

package info.yiwen.thread.safe;

/**
 * 该对象是一个线程安全的对象,他虽然有一个state属性,但是是放在ThreadLocal里的,
 * 也就是说表面上看state属性是属于本类的,其实是属于当前线程的。
 * 
 * 因为每个线程实际上拥有一个state的副本,因此,state属性是不共享的,除此之外,该类也没有其他的共享的属性,
 * 因此该类是线程安全的,可以作为单例对象。
 * 
 * 
 * 项目名称:ThreadSafeClass  
 * 类名称:ThreadSafeWithThreadLocal  
 * 类描述:暂无
 * 创建人:xueshishasha  
 * 创建时间:2012-6-7 下午10:02:35  
 * 修改备注:
 * @version
 */
public class ThreadSafeWithThreadLocal {
	private final static ThreadLocal<Boolean> state = new ThreadLocal<Boolean>();
	
	public ThreadSafeWithThreadLocal(boolean state) {
		this.state.set(state);
	}
	
	public boolean checkState() {
		return state.get();
	}

	public boolean getState() {
		return this.state.get();
	}

	public void setState(boolean state) {
		this.state.set(state);
	}
	
	
}


方法2:使用同步关键字synchronized

package info.yiwen.thread.safe;


/**
 * 该类也是线程安全的,该类有一个共享属性state,但是对state状态进行写的方法上都用了sysnchronized同步语句
 * 
 * 项目名称:ThreadSafeClass  
 * 类名称:ThreadSafeWithSynchronized  
 * 类描述:暂无
 * 创建人:xueshishasha  
 * 创建时间:2012-6-7 下午10:13:50  
 * 修改备注:
 * @version
 */
public class ThreadSafeWithSynchronized {
	
	private Boolean state;
	
	public boolean checkState() {
		return state;
	}

	public boolean isState() {
		return state;
	}

	public void setState(boolean state) {
		synchronized (this.state) {
			this.state = state;
		}
	}
	
	
}


方法3:使用锁

package info.yiwen.thread.safe;

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;


/**
 * 该类也是线程安全的,该类有一个共享属性state,但是对state状态进行写的方法上都用了lock锁同步
 * 
 * 项目名称:ThreadSafeClass  
 * 类名称:ThreadSafeWithSynchronized  
 * 类描述:暂无
 * 创建人:xueshishasha  
 * 创建时间:2012-6-7 下午10:13:50  
 * 修改备注:
 * @version
 */
public class ThreadSafeWithLock {
	
	private Boolean state;
	
	private final Lock lock = new ReentrantLock();
	
	public boolean checkState() {
		return state;
	}

	public boolean isState() {
		return state;
	}

	public void setState(boolean state) {
		lock.lock();
		try {
			this.state = state;
		} finally {
			lock.unlock();
		}
	}
	
	
}


方法4:使用Atomic类型

package info.yiwen.thread.safe;

import java.util.concurrent.atomic.AtomicBoolean;

/**
 * 该类是线程安全的,该类有一个属性,是用AtomicBoolean实现的,
 * Atomic类型会维护好线程安全以及他所持有的值的访问权限
 * 
 * 项目名称:ThreadSafeClass  
 * 类名称:ThreadSafeWithAtomicType  
 * 类描述:暂无
 * 创建人:xueshishasha  
 * 创建时间:2012-6-7 下午10:59:26  
 * 修改备注:
 * @version
 */

public class ThreadSafeWithAtomicType {
	private AtomicBoolean state = new AtomicBoolean();
	
	public boolean checkState() {
		return state.get();
	}

	public boolean getState() {
		return state.get();
	}

	public void setState(boolean state) {
		this.state.set(state);
	}
}





还有更多方法??欢迎跟帖!

 

   发表时间:2012-06-08  
用volatile修饰变量,是否也能实现类似的功能?
0 请登录后投票
   发表时间:2012-06-09  
tessykandy 写道
用volatile修饰变量,是否也能实现类似的功能?

volatile有可见性,但没有原子性
0 请登录后投票
   发表时间:2012-06-09  
543089122 写道
tessykandy 写道
用volatile修饰变量,是否也能实现类似的功能?

volatile有可见性,但没有原子性


对的  在读的时候可以直接读,写的时候还是需要synchronized或者锁
0 请登录后投票
   发表时间:2012-06-11  
287854442 写道
543089122 写道
tessykandy 写道
用volatile修饰变量,是否也能实现类似的功能?

volatile有可见性,但没有原子性


对的  在读的时候可以直接读,写的时候还是需要synchronized或者锁


楼主总结不错。不过,读的时候也需要同步或加锁处理的,否则不能保证可见性,可能读取失效数据。
0 请登录后投票
   发表时间:2012-06-12  
不错哇,有点象"一秒变格格"的速度了.
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics