在写入共享资源之前获取 WriteLock
Acquire WriteLock before writing shared resource
我是多线程的初学者,在 ReadWriteLock
上看到了这个例子。
记分牌
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
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();
}
}
}
}
主要
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
中更新 health
变量,我们需要获取 WriteLock
因为我们正在更新共享变量 ?
我不知道你到底遇到了什么问题,但我认为的问题是:
1) 你应该将 scoreUpdated 和 health 变量设置为 public 和 volatile,目前它分别是私有的和默认的。
2) 当您在释放之前在方法 getMatchHealth() 中获取写入锁定时,您将再次获取刚刚释放的读取锁定。
Wont in the ScoreBoard
while updating the health
variable , we need to acquire the WriteLock
since we are updating a shared variable ?
class 的 getMatchHealth()
方法在不持有写锁的情况下对共享 health
变量执行修改是正确的。 class 中没有其他机制来同步这些写入,当两个线程在同一个 ScoreBoard
上调用 getMatchHealth()
而没有进行某种形式的外部同步时,这会产生数据竞争。这似乎是该方法中的一个缺陷,而且该方法似乎还有其他一些更微妙的同步问题。
然而,所提供的程序似乎根本没有调用 getMatchHealth()
,而其他 ScoreBoard
方法似乎没有同步缺陷,因此所提供的特定程序不受缺陷。尽管如此,除非这些缺陷是故意的——例如,出于教学目的——我建议寻找比提供示例程序的教程更好的教程来源 material。
我是多线程的初学者,在 ReadWriteLock
上看到了这个例子。
记分牌
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
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();
}
}
}
}
主要
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
中更新 health
变量,我们需要获取 WriteLock
因为我们正在更新共享变量 ?
我不知道你到底遇到了什么问题,但我认为的问题是: 1) 你应该将 scoreUpdated 和 health 变量设置为 public 和 volatile,目前它分别是私有的和默认的。
2) 当您在释放之前在方法 getMatchHealth() 中获取写入锁定时,您将再次获取刚刚释放的读取锁定。
Wont in the
ScoreBoard
while updating thehealth
variable , we need to acquire theWriteLock
since we are updating a shared variable ?
class 的 getMatchHealth()
方法在不持有写锁的情况下对共享 health
变量执行修改是正确的。 class 中没有其他机制来同步这些写入,当两个线程在同一个 ScoreBoard
上调用 getMatchHealth()
而没有进行某种形式的外部同步时,这会产生数据竞争。这似乎是该方法中的一个缺陷,而且该方法似乎还有其他一些更微妙的同步问题。
然而,所提供的程序似乎根本没有调用 getMatchHealth()
,而其他 ScoreBoard
方法似乎没有同步缺陷,因此所提供的特定程序不受缺陷。尽管如此,除非这些缺陷是故意的——例如,出于教学目的——我建议寻找比提供示例程序的教程更好的教程来源 material。