Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/google-app-engine/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 是否可能在Google App Engine中具有同步访问的全局对象?_Java_Google App Engine - Fatal编程技术网

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;
    }