我在这里有这个代码块,我需要确保rankedPlayersWaitingForMatch
在线程之间正确同步。我打算使用synchronize
,但由于if
语句中使用了变量,我认为不会在这里工作。我在网上阅读了关于final Lock lock = new ReentrantLock();
的内容,但我对如何在这种情况下使用try/finally
块正确使用它感到困惑。我可以快速举个例子吗?感谢
// start synchronization
if (rankedPlayersWaitingForMatch.get(rankedType).size() >= 2) {
Player player1 = rankedPlayersWaitingForMatch.get(rankedType).remove();
Player player2 = rankedPlayersWaitingForMatch.get(rankedType).remove();
// end synchronization
// ... I don't want this all to be synchronized, just after the first 2 remove()
} else {
// end synchronization
// ...
}
答案 0 :(得分:4)
synchronize
有两种方法 - 你想要的方法是......
boolean shortQueue = true;
synchronize (rankedPlayersWaitingForMatch) {
if (rankedPlayersWaitingForMatch.get(rankedType).size() >= 2) {
shortQueue = false;
Player player1 = rankedPlayersWaitingForMatch.get(rankedType).remove();
Player player2 = rankedPlayersWaitingForMatch.get(rankedType).remove();
}
}
if (shortQueue) {
// this was your else clause
} else {
// this was the rest of the processing
}
需要注意的是,您要同步代码块,而不是数据(即使目标是保护数据)。因此,您还需要同步触摸该变量的任何其他代码区域,例如将新玩家添加到队列中的任何代码。
有更复杂的方法可以表现得更好,但是这个方法会起作用并且很容易纠正。
答案 1 :(得分:3)
这是你想要做的:
boolean has_players = false;
Player player1;
Player player2;
synchronize (rankedPlayersWaitingForMatch) {
if (rankedPlayersWaitingForMatch.get(rankedType).size() >= 2) {
player1 = rankedPlayersWaitingForMatch.get(rankedType).remove();
player2 = rankedPlayersWaitingForMatch.get(rankedType).remove();
has_players = true;
}
}
if(has_players){
// ... I don't want this all to be synchronized, just after the first 2 remove()
}
else{
// ...
}
答案 2 :(得分:2)
虽然旗帜的想法有效,但最不实用的解决方案是重写代码。
private PlayerPair pickPlayers( Type rankedType ) {
synchronized( rankedPlayersWaitingForMatch ) {
if (rankedPlayersWaitingForMatch.get(rankedType).size() >= 2) {
Player player1 = rankedPlayersWaitingForMatch.get(rankedType).remove();
Player player2 = rankedPlayersWaitingForMatch.get(rankedType).remove();
return new PlayerPair( player1, player2 );
}
return null;
}
}
在您的通话代码中......
PlayerPair pair = pickPlayers( rankedType );
if( pair != null ) {
...do unsynchronised stuff here...
} else {
...more unsynchronised stuff
}
这更容易理解,更容易理解。