【发布时间】:2016-12-07 15:07:12
【问题描述】:
有人能在这段代码中找到并发错误吗?该代码在一个线程上运行得非常好,但是当我同时启动 2 个线程并调用 addScore 方法时,它正在向树 Map 添加重复项。
compareTO 被覆盖的 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();
}
【问题讨论】:
-
你怎么知道地图中有重复的内容?
-
因为当我调试时,我看到地图对于同一个 userId 有多个键,而当我打印列表时,我也可以看到
-
对我来说,userId 的条目不应该超过一个条目(分数无关紧要),但是对于一个线程来说这很好,但对于两个线程来说却不行
标签: java multithreading concurrency treemap sortedmap