パリティをインポートするには、マルチスレッドのインターフェイスを最適化するために、Excelスプレッドシートのデータ

企業のニーズ、現在のインポートExcelの機能、プロセスは、次のとおりです。、Excelのデータを読み取る輸入要件かどうかを判断するためのデータのすべての部分のバックグラウンドチェックを渡し、フロント、輸入プレビューショーに戻ります。(応答するための遠位待ち、難しいです)。ユーザーは、[インポート]ボタン、非同期インポートを(フロントエンド行う方が良い、待っていない)をクリックします。現在のデータインタフェースは現在、3000のデータをサポートするために私を必要とし、唯一の300をサポートしています。

問題解決、批判的思考です。

  まず、データが300より大きい場合、判断を参照してください、読書テーブルの場所を見つけ、界面での直接のリターンを見て。3000に300を入れてください。

  そして、データのチェックサム分析をインポートし、データチェックが何であるか、データがデータベースからです。データベースクエリからのたびに、それは確かに遅いです。でも、Redisのクエリキャッシュ、だけでなく、ネットワークの消費量は、キャッシュの圧力を高めます。スタンドアローンありますがRedisのクエリパフォーマンス120 000回/秒、この劇は、それがシステムを使用して40人の崩壊を引き起こした場合120 000 3000は、40で割りました。同じデータが、3000をチェックする必要があり、それは愚かではないでしょうか?だから、データベースクエリにすべてのクエリを削減することは、一度だけ最後までメソッド呼び出しをチェックし、検索操作の重複を避けるために、この方法では同時実行セーフコンテナのConcurrentHashMapストアのデータを、Redisのキャッシュ、Redisのデータで見つかったキャッシュを追加作成します。

  Map<String, Object> map = new ConcurrentHashMap();
        Object obj = map.get("key");
        if (null == obj){
            //查询缓存,或者数据库
            String value = "数据";
            map.put("key", value);
        }

メソッド内で作成されたオブジェクトは、メソッドの呼び出しが完了すると、スタックをプッシュし、あなたの参照を解放し、それがメモリを解放します。3000における検証のプロセスでは、オブジェクトオブジェクトは、JVMメモリに迅速にかなり再度データベースまたはキャッシュから取得する必要性よりも、再利用することが容易です。これは、スタックレベルのキャッシュ、JVMのキャッシュ、ローカルキャッシュ方法です。

これは考えて、最も重要な考え方です。この方法を達成するために、クエリのできるだけ少ない、クエリ結果を再利用します。

私は、データキャッシュの方法でのConcurrentHashMapを行っていたとき、彼らはテストしました。

結果:800データのインポートチェックをサポートします。先端が10秒以上を要求し、要求がタイムアウトします。

どのようにそれを行うには?

製品、あなたは需要ああを扱うことができません。ああ達成することはできません。で口論。無効口論。

次に使うマルチスレッド最適化技術を。

1.スレッド・プールを作成します。

import java.util.concurrent.ExecutorService;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * 线程池<br/>
 * 
 * 
 * @author 
 * @version 
 */
public class MyExecutor {

   /**
    * 在池中保持的线程的最小数量
    */
   private static final int CorePoolSize = 10;
   /**
    * 线程池中能容纳的最大线程数量,如果超出,则使用RejectedExecutionHandler拒绝策略处理
    */
   private static final int MaximumPoolSize = 200;
   /**
    * 线程的最大生命周期。这里的生命周期有两个约束条件:
    * 一:该参数针对的是超过corePoolSize数量的线程;
    * 二:处于非运行状态的线程。举个例子:如果corePoolSize(最小线程数)为10,maxinumPoolSize(最大线程数)为20,
    * 而此时线程池中有15个线程在运行,过了一段时间后,其中有3个线程处于等待状态的时间超过keepAliveTime指定的时间,
    * 则结束这3个线程,此时线程池中则还有12个线程正在运行。
    */
   private static final int KeepAliveTime = 30;
   /**
    * 等待任务队列大小
    */
   private static final int Capacity = 10000;
   
   private static final ExecutorService pool = new ThreadPoolExecutor(CorePoolSize, MaximumPoolSize, KeepAliveTime, TimeUnit.SECONDS, new LinkedBlockingDeque<>(Capacity));
   


   public static ExecutorService getPool(){
      return pool;
   }
   
}

2.取得結果を容易にするために、順序付けられたセットの戻り値を受信するためのスレッドプールのタスクを作成します。

 List<Future<Object>> futureList = new LinkedList<>();

3.スレッドプールを取得します。

       //获取线程池
        ExecutorService pool = MyExecutor.getPool(); 

4.読むExcelスプレッドシートデータ、各列を通して、マルチスレッドタスクに提出されたデータの各行。

        //提交Callable任务到线程池
        Future<Object> future  = pool.submit(new Callable<Object>() {
            @Override
            public Object call() throws Exception {
                // 每条数据的计算
                return null;
            }
        });

         //把单个结果加入有序集合中。
        futureList.add(future);

トラバーサルfutureListの取得結果。

 for (Future<Object> oneFuture : futureList) {
            try {
                //每一个任务的结果,阻塞方法,一直等待到计算任务完成。
                Object result = oneFuture.get();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

6.このように、すべての結果の組み合わせが返されます。転換のこの方法を使用してスレッドプールを完了します。

7.この時点で、問題は、3000件のデータを浮上している、各データは、IDを持って、どのように複数のスレッド、処理されたIDは繰り返さないようにしましょう、重複はそれをマークすることができますか?

今回は私が同時のセキュリティ設定を使用===> ConcurrentSkipListSetの

     // 并发安全,去重复
        ConcurrentSkipListSet<Integer> idSet = new ConcurrentSkipListSet<>();

      boolean flag =idSet.add(id);
        if (!flag){
            //添加失败,说明数据重复。
        }

ソースConcurrentSkipListSetのadd()メソッドを見てみましょう:

    /**
     * Adds the specified element to this set if it is not already present.
     * More formally, adds the specified element {@code e} to this set if
     * the set contains no element {@code e2} such that {@code e.equals(e2)}.
     * If this set already contains the element, the call leaves the set
     * unchanged and returns {@code false}.
     *
     * @param e element to be added to this set
     * @return {@code true} if this set did not already contain the
     *         specified element
     * @throws ClassCastException if {@code e} cannot be compared
     *         with the elements currently in this set
     * @throws NullPointerException if the specified element is null
     */
    public boolean add(E e) {
        return m.putIfAbsent(e, Boolean.TRUE) == null;
    }

Googleと上記の説明翻訳:
      指定された要素が存在しない場合は、このコレクションに追加します。
      場合は、より正式には、指定された要素{@code eは}このセットに追加された
     セットは{@codeのe.equals(E2)}の要素{@codeのE2}を含んでいません。
      セットがすでに要素が含まれている場合、呼び出しはセットを終了します
     変わらず、リターンは{偽} @code

ここで説明id我々は大量使用が完全に正しいことを行きます。

私たちは、get()メソッドのソースコードの未来を見てみましょう:

    /**
     * Waits if necessary for the computation to complete, and then
     * retrieves its result.
     *
     * @return the computed result
     * @throws CancellationException if the computation was cancelled
     * @throws ExecutionException if the computation threw an
     * exception
     * @throws InterruptedException if the current thread was interrupted
     * while waiting
     */
    V get() throws InterruptedException, ExecutionException;

翻訳:する計算のために待機し、必要に応じて 。完成した後、その結果を取得しますが、
                     必要な計算が完了するのを待ってから、結果を取得

だから、将来のget()メソッドを待ってブロックされています。

 

これは、私が最適化されたデータ、データに応じてデータ300、800〜10秒の先頭から7〜3000秒の応答を行っています。

タスクを完了するだけでなく、パフォーマンスが向上します。

この時点で、スレッド・プール、今後、呼び出し可能なセキュリティおよび同時コンテナクラスのConcurrentHashMap、ConcurrentSkipListSetの技術を使用して、

大幅に私のマルチスレッド、並行プログラミング手法を改善しました。思考の飛躍であるレベルのデータキャッシュ、JVMのキャッシュを、スタックの方法があります。

 

おすすめ

転載: www.cnblogs.com/itbac/p/11291706.html