最近遇到一个问题,就是会碰到将不同平台的用户汇总,一个账号可以无痕登录到三个平台上,
让用户切换平台的时候不需要重新登录。后来通过多线程汇总把各个平台的账号取过来,
在本地保留一份但是不存储密码,为了不会出现密码不一致的问题。
下面就模拟一下:数据源
package com.thread;
import java.util.HashMap;
import java.util.Map;
/**
* 模拟数据库
* @author lwl
*
*/
public class Datas {
//模拟静态数据库数据
public static Map<String, String> MAP1 = new HashMap<String,String>();
public static Map<String, String> MAP2 = new HashMap<String,String>();
public static Map<String, String> MAP3 = new HashMap<String,String>();
static{
MAP1.put("abc", "123");
MAP1.put("def", "456");
MAP1.put("asd", "123");
MAP2.put("abc", "456");
MAP2.put("def", "456");
MAP3.put("abc", "123");
MAP3.put("asd", "1231");
}
/**
* 根据版本号获取数据库数据
* @param version
* @return
*/
public static final Map<String, String> getDate(String version){
switch (version) {
case "1":
return MAP1;
case "2":
return MAP2;
case "3":
return MAP3;
default:
return null;
}
}
}
创建用户对象,每个平台的手机号是唯一的
package com.thread;
public class User {
private int id;
private long accountId;
private String mobile;
private String password;
private String version;
// -1 表示未查询到数据 0表示密码错误 1表示都正确
private String state;
public User(){}
public User(String mobile,String password,String version){
this.mobile = mobile;
this.password = password;
this.version = version;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public long getAccountId() {
return accountId;
}
public void setAccountId(long accountId) {
this.accountId = accountId;
}
public String getMobile() {
return mobile;
}
public void setMobile(String mobile) {
this.mobile = mobile;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getVersion() {
return version;
}
public void setVersion(String version) {
this.version = version;
}
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
@Override
public String toString() {
String info = "User [id=" + id + ", accountId=" + accountId + ", mobile="
+ mobile + ", password=" + password + ", version=" + version
+ ", state=" + state + "]";
System.out.println(info);
return info;
}
}
创建用户线程读取数据源:
package com.thread;
import java.util.Map;
public class UserThread extends Thread {
private User user;
//模拟用户的accountID
private long accountId;
public UserThread(){}
public UserThread(User user) {
super();
this.user = user;
}
@Override
public void run() {
//模拟从数据库中获取数据
Map<String, String> data = Datas.getDate(user.getVersion());
//校验手机号码是否存在
if(data.get(user.getMobile())!=null){
//校验密码是否正确
if(data.get(user.getMobile()).equals(user.getPassword())){
//都正确
user.setState("1");
//将用户的accountID 填充到user中,模拟数据
user.setAccountId(getAccountId());
}else{
//密码错误
user.setState("0");
}
}else{
user.setState("-1");
}
}
//各个版本的accountID 取不同的值
public long getAccountId() {
accountId = 3;
if(user.getVersion().equals("1")){
accountId = 1;
}else if(user.getVersion().equals("2")){
accountId = 2;
}
return accountId;
}
public void setAccountId(long accountId) {
this.accountId = accountId;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
}
创建添加用户到数据库的线程:
package com.thread;
import java.util.List;
public class AddUserThread extends Thread {
private List<User> user;
public AddUserThread(){}
public AddUserThread(List<User> user) {
super();
this.user = user;
}
@Override
public void run() {
System.out.println("开始执行添加线程");
for (User u : user) {
addLocal(u);
}
System.out.println("已经结束添加线程");
}
public List<User> getUser() {
return user;
}
public void setUser(List<User> user) {
this.user = user;
}
/**
* 新起一个线程给用户添加到本地微信
* @param user1
* @param user2
* @param user3
*/
public void newThread(List<User> user){
for (User u : user) {
addLocal(u);
}
}
/**
* 将不存在数据库中的用户添加到数据库
* @param user
*/
public void addLocal(User user){
if(user.getState().equals("-1")){
//新添加账号
//accountId = add(u1); 添加到平台数据库中
//user.setAccountId(accountId);
System.out.println("我在平台 "+user.getVersion()+" 上添加了一个新账号");
}
//通过 手机号码和版本查询是否已经存在
// if(findUserByMobileAndVersion(user.getMobile(),user.getVersion())==null){
// //如果不存在则添加到数据库中
// addUser(user);
// }
}
}
最后就是写测试类了:
package com.thread;
import java.util.ArrayList;
import java.util.List;
public class UserThreadTest extends Thread {
public static void main(String[] args) {
//手机号和密码一样 只有版本不一样
String mobile = "asd";
String password = "123";
User u1 = new User(mobile,password,"1");
User u2 = new User(mobile,password,"2");
User u3 = new User(mobile,password,"3");
List<User> userList = new ArrayList<User>();
userList.add(u1);
userList.add(u2);
userList.add(u3);
//启动方法
start(userList);
}
/**
* 启动方法
* @param userList
*/
public static void start(List<User> userList){
List<UserThread> userThreadLiset = new ArrayList<UserThread>();
for (User user : userList) {
userThreadLiset.add(getUserThread(user));
}
for (UserThread userThread : userThreadLiset) {
closeUserThread(userThread);
//打印信息
userThread.getUser().toString();
}
//对结果集进行校验
validate(userList);
}
/**
* 关闭超时的线程
* @param thread
*/
public static void closeUserThread(UserThread thread){
if(thread.getAccountId()==0 && thread.isAlive()){
System.out.println("线程终结");
thread.interrupt();//中断超时的线程
}
}
/**
* 创建用户线程
* @param u1
* @return
*/
public static UserThread getUserThread(User u1){
UserThread thread1 = new UserThread(u1);
thread1.start();
try {
//主线程等待时间不超过10秒,若超过,则主线程直接走
thread1.join(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return thread1;
}
/**
* 对各版本的账号进行校验
* @param user1
* @param user2
* @param user3
*/
public static void validate(List<User> user){
//用于记录结果集
int result = 0;
//用于记录不存在平台的数量
int length = 0;
//用于记录第一个可以登录的平台位置
int index = 0;
for (int i = 0; i < user.size(); i++) {
String state = user.get(i).getState();
//如果有一个登录成功 则表明可以登录
if(state.equals("1")){
result = 1;
break;
}else if(state.equals("-1")){//计算几个平台账号是空的
length++;
}
}
//说明有平台账号是可以登录成功的
if(result==1){
User u = user.get(index);
System.out.println("我的账号有效 ,现在使用的是平台:"+u.getVersion());
/****************************起一个新的线程 让他在后台进行账号添加***************************************/
//这个新起的线程会有一个问题,就是如果用户在1.0上登录成功,而2.0上没有该账号,则会将登录账号添加到数据库的时候,用户切换了平台,会发现没有2.0的账号
// (是由于添加账号的时候需要时间等待,而用户恰巧在等待期间切换了平台)
AddUserThread t = new AddUserThread(user);
t.start();
}else if(length==user.size()){
//如果不存在的数量和集合大小一样 说明所有平台都不存在
System.out.println("该账号未注册过");
}else{
//剩余的就表示 该手机号码存在 而密码错误
System.out.println("对不起 您的密码输入错误");
}
}
}
“`