多线程知识点整理
有状态对象与无状态对象
1、线程安全
要搞清楚有状态对象和无状态对象,首先需要弄清楚线程安全的问题。如果你的代码所在的进程中有多个线程在同时运行,而这些线程可能会同时运行这段代码。如果每次运行结果和单线程运行的结果是一样的,而且其他的变量的值也和预期的是一样的,那么就是线程安全的。
或者说,一个类或者程序所提供的接口对于线程来说是原子操作或者多个线程之间的切换不会导致该接口的执行结果存在二义性,也就是说我们不用考虑同步的问题。
线程安全问题都是由全局变量及静态变量引起的。 若每个线程中对全局变量、静态变量只有读操作,而无写操作,一般来说,这个全局变量是线程安全的;若有多个线程同时执行写操作,一般都需要考虑线程同步,否则就可能影响线程安全。
2、关于线程安全
1) 常量始终是线程安全的,因为只存在读操作。
2) 每次调用方法前都新建一个实例是线程安全的,因为不会访问共享的资源(共享堆内存)。
3) 局部变量是线程安全的。因为每执行一个方法,都会在独立的空间创建局部变量,它不是共享的资源。局部变量包括方法的参数变量和方法内变量。
3、有状态和无状态对象
有状态就是有数据存储功能。有状态对象(Stateful Bean),就是有实例变量的对象 ,可以保存数据,是非线程安全的。在不同方法调用间不保留任何状态。其实就是有数据成员的对象。
无状态就是一次操作,不能保存数据。无状态对象(Stateless Bean),就是没有实例变量的对象。不能保存数据,是不变类,是线程安全的。具体来说就是只有方法没有数据成员的对象,或者有数据成员但是数据成员是可读的对象。
4、代码示例
/**
* 有状态bean,有state,user等属性,并且user有存偖功能,是可变的。
*/
public class StatefulBean {
public int state;
// 由于多线程环境下,user是引用对象,是非线程安全的
public User user;
public int getState() {
return state;
}
public void setState(int state) {
this.state = state;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
}
/**
* 无状态bean,不能存偖数据。因为没有任何属性,所以是不可变的。只有一系统的方法操作。
*/
public class StatelessBeanService {
// 虽然有billDao属性,但billDao是没有状态信息的,是Stateless Bean.
BillDao billDao;
public BillDao getBillDao() {
return billDao;
}
public void setBillDao(BillDao billDao) {
this.billDao = billDao;
}
public List<User> findUser(String Id) {
return null;
}
}