首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在编写共享资源之前获取WriteLock

在编写共享资源之前获取WriteLock
EN

Stack Overflow用户
提问于 2019-02-07 14:20:47
回答 2查看 36关注 0票数 0

我是多线程的初学者,在ReadWriteLock上看到了这个例子。

ScoreBoard

代码语言:javascript
复制
public class ScoreBoard {
private boolean scoreUpdated = false;
private int score = 0;
    String health = "Not Available";
final ReentrantReadWriteLock rrwl = new ReentrantReadWriteLock();
public String getMatchHealth() {
    rrwl.readLock().lock();
    if (scoreUpdated) {
        rrwl.readLock().unlock();
        rrwl.writeLock().lock();
        try {
          if (scoreUpdated) {
              score = fetchScore();
              scoreUpdated = false;
          }
          rrwl.readLock().lock();
        } finally {
          rrwl.writeLock().unlock(); 
        }   
    }   
    try {
         if (score % 2 == 0 ){
              health = "Bad Score";
          } else {
              health = "Good Score";
          }
    } finally {
          rrwl.readLock().unlock();
        }
    return health;
}
public void updateScore() {
    try {
        rrwl.writeLock().lock();
        //perform more task here
        scoreUpdated = true;
    }finally {
        rrwl.writeLock().unlock();
    }
}
private int fetchScore() {
    Calendar calender = Calendar.getInstance();
    return calender.get(Calendar.MILLISECOND);
}
}

ScoreUpdateThread

代码语言:javascript
复制
public class ScoreUpdateThread implements Runnable {
private ScoreBoard scoreBoard;
public ScoreUpdateThread(ScoreBoard scoreTable) {
    this.scoreBoard = scoreTable;
}
@Override
public void run() {
    for(int i= 0; i < 5; i++) {
        System.out.println("Score Updated.");       
        scoreBoard.updateScore();
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}
}

代码语言:javascript
复制
public class Main {
public static void main(String[] args) {
    final int threadCount = 2;
    final ExecutorService exService = Executors.newFixedThreadPool(threadCount);
    final ScoreBoard scoreBoard = new ScoreBoard();
    exService.execute(new ScoreUpdateThread(scoreBoard));
    exService.execute(new ScoreHealthThread(scoreBoard));           
    exService.shutdown();
}
}   

在更新ScoreBoard变量的同时,我们需要获取WriteLock,因为我们正在更新一个共享变量?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-02-07 18:57:14

在更新ScoreBoard变量的同时,我们需要获取WriteLock,因为我们正在更新一个共享变量?

正确的是,类的getMatchHealth()方法在不保留写锁的情况下执行共享health变量的修改。类中没有用于同步这些写入的其他机制,当两个线程在相同的getMatchHealth()上调用ScoreBoard而不进行某种形式的外部同步时,这会产生数据竞争。这似乎是方法中的一个缺陷,而且该方法似乎还存在其他一些更微妙的同步问题。

然而,所提供的程序似乎从未调用过getMatchHealth(),而其他ScoreBoard方法似乎没有同步缺陷,因此所提供的特定程序不受这些缺陷的影响。尽管如此,除非这些缺陷是有意的--例如,为了教学目的--我建议找到一个比提供示例程序更好的教程材料来源。

票数 1
EN

Stack Overflow用户

发布于 2019-02-07 15:12:06

我不知道您到底面临什么问题,但我认为问题是: 1)您应该将scoreUpdated和health变量设置为公共和可变变量,目前它分别是私有的和默认的。

2)在释放方法getMatchHealth()之前,当您在方法()中使用写锁时,您将再次使用读锁,而这正是您之前发布的。

票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/54575427

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档