6

顧客 (10000 以上) に価格を送信していますが、以下のコードにはループがあり、計算を待っている顧客の処理に遅延が生じます。

PriceVisibleForCustomer = 価格 + CustomerMargin

価格 - 300 ミリ秒ごとに変更 - 中央ストアから送信され、顧客インスタンスとは関係ありません

CustomerMargn - 顧客の合意/セグメント/管理者の決定などに起因するプラスまたはマイナスの金額。顧客の http セッション中は変更されません。メモリに保持できます。

顧客 - ログイン後にプロセスに参加すると、8 つの製品の価格が急速に変化することがわかります。

多分私はもう少し技術が必要ですか?私はSpring 3/4、Java、Weblogicを持っており、計算された価格を提供するために、このタスク用に別のwebappを作成することさえできました.

Java のスレッドについて考えましたが、10000 人以上の顧客というのはスレッドが多すぎるということでしょうか? このコードを変更するには?アーキテクチャを変更する必要があるかもしれませんが、どうすればよいですか?

/**
     * Sends prices to customer. This method is called very often (300ms) as prices are changing in real time.
     * Customer should see prices also each 300ms
     * @param productId - id of a product that prices will be calculated
     * @param productIdToPriceMap 
     * @param customerIdToMarginMap - this map is changed every time customer logs in or logs out
     */
    private static void sendPricesToCustomers(Long productId,
            Map<Long, BigDecimal> productIdToPriceMap,
            Map<Long, BigDecimal> customerIdToMarginMap) {

        //This loop is blocking last customer from receiving price until all other customers wil have theri prices calculated. I could create threads, 10000+ customers will be logged in, I cant create so much threads... can I?
        for (Long customerId: customerIdToMarginMap.keySet()){
            BigDecimal customerMargin = customerIdToMarginMap.get(customerId);
            BigDecimal priceResult = productIdToPriceMap.get(productId).add(customerMargin);
            //send priceResult to websocket
        }

    }
4

2 に答える 2

1

これはリスナーパターンの簡単な例です。このアプローチがうまくいくかどうかはわかりませんが、いくつかのアイデアを捨てるだけです...

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Vector;

import javax.swing.Timer;

public class Demo {

  public static Product[] PRODUCTS = new Product[]{
      new Product("Computer", 400),
      new Product("Desk", 800),
      new Product("Chair", 70),
      new Product("Printer", 300),
      new Product("Television", 200)
  };

  public static void main(String[] args) throws InterruptedException {
      Customer john = new Customer("John", 3);    
      john.addProduct(PRODUCTS[1]);
      john.addProduct(PRODUCTS[2]);
      john.addProduct(PRODUCTS[3]);


      Customer mary = new Customer("Mary", 2);    
      mary.addProduct(PRODUCTS[1]);
      mary.addProduct(PRODUCTS[2]);
      mary.addProduct(PRODUCTS[4]);


      Thread.sleep(10000);
      System.exit(0);
  }
}

interface IPriceListener {
  public void priceChanged(Product product, int price);
}

class Customer implements IPriceListener {
  String _name;
  int _margin;
  Vector<Product> _products = new Vector<Product>();

  public Customer(String name, int margin){
    _name = name;
    _margin = margin;
  }

  public void addProduct(Product product){
    _products.add(product);
    product.addListener(this);
  }

  public void priceChanged(Product product, int price) {
    System.out.println("[" + _name + "][" + _products.get(_products.indexOf(product)).getName() + "][" + price + "][" + (price + _margin) + "]");
  }
}

class Product implements ActionListener {
  private int _startingPrice;
  private int _currentPrice;

  private String _name;
  private Timer _timer;
  private Vector<IPriceListener> _listeners = new Vector<IPriceListener>();

  public Product(String name, int price) {
    _name = name;
    _startingPrice = _currentPrice = price;
    _timer = new Timer(300, this);
    _timer.start();
  }

  public void addListener(IPriceListener listener) {
    _listeners.add(listener);
  }

  public void removeListener(IPriceListener listener){
    _listeners.remove(listener);
  }

  private void notifyListeners() {
    for(IPriceListener listener : _listeners){
      listener.priceChanged(this, getCurrentPrice());
    }
  }

  public void actionPerformed(ActionEvent e) {
    _currentPrice = _startingPrice + (int)(Math.random() * (5 - (-5))) + (-5);
    notifyListeners();
  }

  public final String getName() {
    return _name;
  }

  private synchronized final int getCurrentPrice() {
    return _currentPrice;
  }
}
于 2015-07-18T16:57:58.750 に答える