有人可以在此代码中找到并发错误吗?代码对于一个线程工作得非常好,但是我很快就会在同一时间启动2个线程并调用addScore方法,它会在树Map中添加重复项。
与被覆盖的被覆盖的pojo如下:
public final class UserHighScore implements Comparable<UserHighScore>{
private final int userId;
private final int value;
public UserHighScore(int userId, int value) {
this.userId = userId;
this.value = value;
}
public int getUserId() {
return userId;
}
public int getValue() {
return value;
}
@Override
public boolean equals(Object obj) {
if (obj == this) return true;
if (!(obj instanceof UserHighScore)) {
return false;
}
UserHighScore userHighScore = (UserHighScore) obj;
return userHighScore.userId==userId;
}
@Override
public int compareTo(UserHighScore uh) {
if(uh.getUserId()==this.getUserId()) return 0;
if(uh.getValue()>this.getValue()) return 1;
return -1;
}
}
这是我用来模拟用户发出请求的代码:
class User implements Runnable
{
private ScoreServiceImpl scoreService=ScoreServiceImpl.getInstance();
CountDownLatch latch;
public User(CountDownLatch latch)
{
this.latch = latch;
}
@Override
public void run() {
for(int i=0;i<5;i++) {
scoreService.addScore(3,Integer.parseInt(Thread.currentThread().getName()),ThreadLocalRandom.current().nextInt(50000));
}
System.out.println(scoreService.getHighScoreList(3));
}
}
创建线程的主要方法是:
public static void main(String[] args) throws InterruptedException {
SpringApplication.run(RestclientApplication.class, args);
CountDownLatch latch = new CountDownLatch(1);
User user1=new User(latch);
User user2=new User(latch);
Thread t1=new Thread(user1);
Thread t2=new Thread(user2);
t1.setName("1");
t2.setName("2");
t1.start();
t2.start();
//latch.countDown();
}
答案 0 :(得分:3)
你的比较搞砸了。您可以使用类似这样的单线程获得相同的结果
ScoreServiceImpl.getInstance().addScore(0,1,4);
ScoreServiceImpl.getInstance().addScore(0,1,12);
ScoreServiceImpl.getInstance().addScore(0,0,10);
ScoreServiceImpl.getInstance().addScore(0,0,3);
树集通过分而治之的方式工作,它首先检查中间的人。 (将为1,4)并且由于用户不匹配,因此不比较它们并比较这些值。如果它已经比较了用户标识,那么它就会向左移,但是它向右移动并且仅将项目与一个用户标识进行比较
您可以始终比较这两个值,或始终只比较userId,但您无法来回切换。
@Override
public int compareTo(UserHighScore uh) {
return Integer.compare(userId, uh.userId);
}