spring中的bean都是单例模式创建的,始终都是处理一个bean对象,在多用户操作情况下单例模式只跟用户提交操作时间顺序,准确是处理器执行代码的先后顺序有关。
当在service或者controller层中创建了成员变量时,单例模式被破坏,此时涉及到成员变量的全部不同步,需要加synchronized锁才能实现线程同步!
例如:
1.模拟在Controller中加入了成员变量student,破坏了单例模式
package org.example;
//模拟在Controller中加入了成员变量student,破坏了单例模式
public class Controller {
final static Service service =Service.newInstance();
public static void main(String[] args) throws InterruptedException {
final Student student = new Student();
new Thread(new Runnable() {
@Override
public void run() {
service.setStudent(student,18,"小明");
System.out.println(Thread.currentThread().getName()+":"+service.getStudent(student));
}
}).start();
Thread.sleep(10);//保证子线程先执行
System.out.println(Thread.currentThread().getName()+":"+service.getStudent(student));
}
}
2.单例的Service
package org.example;
//单例的Service
public class Service {
private static Service service = new Service();
private Service() {
}
public static Service newInstance() {
return service;
}
public synchronized String getStudent(Student student) {
return student.getName()+student.getAge();
}
public synchronized void setStudent(Student student, Integer age,String name) {
student.setName(name);
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
student.setAge(age);
}
}
3.student类
package org.example;
//student类
public class Student {
private Integer age;
private String name;
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
上述代码在service层中查询和修改都加了锁之后,数据同步了。注意:在student类中加锁是没用的,因为两个set方法为一个原子操作,两个get方法为一个原子操作,在student中加等于每一个都是原子操作。
若不加锁将产生脏读,可自行尝试。