我已經清理並縮短了多用戶遊戲的代碼片段,以顯示我想要完成的操作。所以在這裏,它是:正確處理跨線程共享類的鎖定方式
public class Subject {
public List<IObject> Objects = new List<IObject>();
}
public interface IOpenable
{
void Open(Subject by, params string[] p);
void Close(Subject by, params string[] p);
bool IsOpen { get; }
}
public interface IObject {
void Pickup(Subject by, params string[] p);
void Drop(Subject by, params string[] p);
}
public class Box : IObject, IOpenable
{
bool opened = false;
Subject owner = null;
public void Pickup(Subject subject, params string[] p) {
subject.Objects.Add(this);
this.owner = subject;
}
public void Drop(Subject subject, params string[] p)
{
subject.Objects.Remove(this);
this.owner = null;
}
public void Open(Subject by, params string[] p)
{
this.opened = true;
}
public void Close(Subject by, params string[] p)
{
this.opened = false;
}
public bool IsOpen { get { return opened; } }
}
我想知道的是: 如何防止某些用戶(從另一個線程執行代碼)來打開當前正在由其他一些用戶拿起一個盒子。 我已經想到了一些方法,但我認爲這裏的人經常想出聰明的想法,這可以讓我避免一些愚蠢的設計問題。
編輯:正如在回答提出,要使用鎖關鍵字在打開的方法:這是不是我想要什麼,我會嘗試用解釋是允許什麼,什麼不是:
網絡我們得到的請求以某種方式異步並且如果發佈得很快就會出錯。
- (1)用戶1次發出指令PICKUP BOX
- (2)用戶1次發出指令OPEN BOX
- (3)用戶1所發出命令關閉BOX
- (4)用戶2次發出指令OPEN BOX
- (5)用戶2次發出指令LOOK BOX
- (6)用戶1次發出指令打開框中
我們得到這個順序:
2,3,1,5,4,6
2 - allow
3 - allow
1 - allow [remains in execution and has not set the owner]
5(comes in between 1) - allow
4(comes in between 1) - disallow (not because already open but because 1 is in execution)
6(comes in between 1) - allow since it is from user 1, and he is currently picking it up
謝謝!
我發佈將滿足新的條件解決方案 - TryOpen( )將在(3)執行時返回false。如果需要,您可以將相同的方法應用於其他方法以滿足進一步的條件。 – 2011-04-12 04:07:52
在tcp中,據我所知,消息的順序是保證的,所以可能發生的最壞情況是1,3,4,2 - 這是你必須在你的代碼中處理的,意思是記住誰'擁有'哪個對象 – 2011-04-12 04:09:26
到目前爲止正如我所看到的,如果有時候命令不同步,如果它們發出的速度非常快,似乎每個命令都有一個連接,而不是一個連接,但是不是我的代碼的一部分,我不是專家......:/ – 2011-04-12 04:16:06