Java 是否可能在Google App Engine中具有同步访问的全局对象?
我正在开发一个应用程序,它的对象必须对所有实例都可用,但对对象中的某些方法也有同步访问 例如,我有一个对象:Java 是否可能在Google App Engine中具有同步访问的全局对象?,java,google-app-engine,Java,Google App Engine,我正在开发一个应用程序,它的对象必须对所有实例都可用,但对对象中的某些方法也有同步访问 例如,我有一个对象: public class PlanetID implements Serializable { public PlanetID() { id = 0; } public long generateID() { id++; return id; } private long id; } 它是一个简
public class PlanetID implements Serializable {
public PlanetID() {
id = 0;
}
public long generateID() {
id++;
return id;
}
private long id;
}
它是一个简单的对象,可以创建一个长的(id)序列。每次该对象都必须生成一个唯一的id。目前,我有一个静态同步方法,它处理数据存储访问和存储以及MemCache访问和存储。它适用于这个特定的方法,但我已经看到了更复杂的对象的问题,这些对象要求用户能够访问非同步变量和同步变量
是否有某种方法使对象成为全局对象,并在访问同步对象时允许同步方法和非同步方法以及对象的存储
编辑:我认为人们过于关注我给他们的示例,而没有关注更大的问题,即拥有一个可以被所有实例访问的全局变量,对特定方法进行同步访问,同时允许异步访问其他方法
这里有一个更好的例子,希望它能让事情变得更清楚
前
公共类市场实现可序列化{
公开市场(){
矿化度1=新阵列列表();
矿化2=新阵列列表();
矿化3=新的阵列列表();
矿化度4=新阵列列表();
}
public void addListing(int-mineral、String-userID、int-price、long-amount){//不需要同步访问
开关(矿物){
案例1:
1.添加(新列表(用户ID、价格、金额));
打破
案例2:
2.添加(新列表(用户ID、价格、金额));
打破
案例3:
3.添加(新列表(用户ID、价格、金额));
打破
案例4:
4.添加(新列表(用户ID、价格、金额));
打破
}
}
购买的公共void(int mineral,String userID,long amount){//需要同步访问
ArrayList=null;
开关(矿物){
案例1:
矿物学列表=矿物学1;
打破
案例2:
矿物学列表=矿物学2;
打破
案例3:
矿物学列表=矿物学3;
打破
案例4:
矿物学列表=矿物学4;
打破
}
Listing remove=null;
对于(列表:矿物列表)
if(listing.userID==userID)
如果(listing.amount>amount){
listing.amount-=金额;
返回;
}否则{
删除=列表;
打破
}
列表。删除(删除);
集合。排序(列表);
}
公共JSONObject toJSON(int mineral){//不需要同步访问
JSONObject JSONObject=新的JSONObject();
试一试{
开关(矿物){
案例1:
对于(清单:1)
累积(Player.1,listing.toJSON());
打破
案例2:
对于(清单:2)
累计(Player.2,listing.toJSON());
打破
案例3:
对于(清单:3)
累积(Player.3,listing.toJSON());
打破
案例4:
对于(清单:4)
累积(Player.4,listing.toJSON());
打破
}
}捕获(JSONException e){
}
返回jsonObject;
}
公共静态最终int=1=0;
公共静态最终int 2=1;
公共静态最终int=3=2;
公共静态最终int=4=3;
私人ArrayList矿藏1;
私人ArrayList矿藏2;
私人ArrayList矿藏3;
私人ArrayList矿物学家4;
私有类清单实现了可序列化、可比较的{
公开列表(字符串用户ID、整数价格、长金额){
this.userID=userID;
这个价格=价格;
这个。金额=金额;
}
公共JSONObject toJSON(){
JSONObject JSONObject=新的JSONObject();
试一试{
put(“UserID”,UserID);
jsonObject.put(“价格”,价格);
jsonObject.put(“金额”,金额);
}捕获(JSONException e){
//TODO自动生成的捕捉块
e、 printStackTrace();
}
返回jsonObject;
}
@凌驾
公共整数比较(列表){
返回(价格
}如评论中所述-您可以使用事务来实现这一点:
索引
和someText
属性创建或更新SomeObject
实体请注意,上述解决方案的写入瓶颈约为1次写入/秒。如果您需要更高性能的解决方案,您可以考虑使用后端实例。事务之外的其他方法是使用单个后端实例来保持全局对象,并使对该对象的所有访问都在那里同步。所有其他实例都需要使用URLFetch访问此后端实例以获取对象的状态 这是一个可怕的性能瓶颈,但如果你的应用程序想要顺利扩展,请不要使用它,我只是指出了其他方法。事实上,如果可能,请避免在分布式应用程序上使用同步全局对象
public class Market implements Serializable {
public Market() {
mineral1 = new ArrayList<Listing>();
mineral2 = new ArrayList<Listing>();
mineral3 = new ArrayList<Listing>();
mineral4 = new ArrayList<Listing>();
}
public void addListing(int mineral, String userID, int price, long amount) { //Doesn't require synchronized access
switch (mineral) {
case MINERAL1:
mineral1.add(new Listing(userID, price, amount));
break;
case MINERAL2:
mineral2.add(new Listing(userID, price, amount));
break;
case MINERAL3:
mineral3.add(new Listing(userID, price, amount));
break;
case MINERAL4:
mineral4.add(new Listing(userID, price, amount));
break;
}
}
public void purchased(int mineral, String userID, long amount) { //Requires synchronized access
ArrayList<Listing> mineralList = null;
switch (mineral) {
case MINERAL1:
mineralList = mineral1;
break;
case MINERAL2:
mineralList = mineral2;
break;
case MINERAL3:
mineralList = mineral3;
break;
case MINERAL4:
mineralList = mineral4;
break;
}
Listing remove = null;
for (Listing listing : mineralList)
if (listing.userID == userID)
if (listing.amount > amount) {
listing.amount -= amount;
return;
} else{
remove = listing;
break;
}
mineralList.remove(remove);
Collections.sort(mineralList);
}
public JSONObject toJSON(int mineral) { //Does not require synchronized access
JSONObject jsonObject = new JSONObject();
try {
switch (mineral) {
case MINERAL1:
for (Listing listing : mineral1)
jsonObject.accumulate(Player.MINERAL1, listing.toJSON());
break;
case MINERAL2:
for (Listing listing : mineral2)
jsonObject.accumulate(Player.MINERAL2, listing.toJSON());
break;
case MINERAL3:
for (Listing listing : mineral3)
jsonObject.accumulate(Player.MINERAL3, listing.toJSON());
break;
case MINERAL4:
for (Listing listing : mineral4)
jsonObject.accumulate(Player.MINERAL4, listing.toJSON());
break;
}
} catch (JSONException e) {
}
return jsonObject;
}
public static final int MINERAL1 = 0;
public static final int MINERAL2 = 1;
public static final int MINERAL3 = 2;
public static final int MINERAL4 = 3;
private ArrayList<Listing> mineral1;
private ArrayList<Listing> mineral2;
private ArrayList<Listing> mineral3;
private ArrayList<Listing> mineral4;
private class Listing implements Serializable, Comparable<Listing> {
public Listing(String userID, int price, long amount) {
this.userID = userID;
this.price = price;
this.amount = amount;
}
public JSONObject toJSON() {
JSONObject jsonObject = new JSONObject();
try {
jsonObject.put("UserID", userID);
jsonObject.put("Price", price);
jsonObject.put("Amount", amount);
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return jsonObject;
}
@Override
public int compareTo(Listing listing) {
return (price < listing.price ? -1 : (price == listing.price ? 0 : 1));
}
public String userID;
public int price;
public long amount;
}