Java HashMapに基づくデッドサイクルのヒントの詳細
2733 ワード
一、単一スレッドをマルチスレッドに改造するのも技術的な仕事である.
ネズミおじさんのブログに書いてあるように、もともとは単一スレッドのアプリケーションでしたが、「その後、私たちのプログラムの性能に問題があったので、マルチスレッドになる必要がありました.そこで、マルチスレッドになってからオンラインに着いたら、プログラムが100%CPUを占めていることに気づきました」.
タオバオのエンジニアが暴露した問題を考えると、彼らの技術基礎は一般的にしっかりしていて、彼らさえ間違っていたので、単一スレッドをマルチスレッドに改造するのは想像していたほど簡単ではないと思います.
宝を洗うエンジニアはどうしたのか、単一スレッドをマルチスレッドに変えるのは難しいのか、既存のマルチスレッド技術を応用することにほかならない.ほら、私は非常に強いスレッド安全意識を持っている.同期、デッドロック、競合条件を知っている.lock freeとスレッド安全容器も知っているし、各種スレッドの安全同期構造も知っている.スレッドを出さないで安全なアプリケーション?
実際には、スレッドセキュリティのアプリケーションは、スレッドセキュリティの基礎と開発経験がしっかりしているからといって、必ずしも作成できるわけではありません.
2つの例を挙げてみましょう.
1、スレッド安全容器を使用してインデックスからデータを取る
多くの人が知っているスレッドセキュリティコンテナは、実際に使用するときにBUGが発生しないとは限らない.以下のコードが典型的だ.
上の関数パラメータlistが最初に要素総数1のリストを入力すると、上のコードに何か問題があるのではないでしょうか.
スレッドセキュリティコンテナについては、以前にも「スレッドセキュリティコンテナの実現方法に深く入り込む」という記事をまとめました.スレッドセキュリティコンテナは本当に安全ではありません.問題のあるコードはここから出ています.
2、マルチスレッド操作メールのミス
また、マルチスレッドアプリケーションシーンの分析が正しくない可能性があります.かつてメール送受信プログラムの性能の問題で、私も大胆にアプリケーションを改造したことがあります.変更すると重大なバグが発生しました.
私が心を痛めてまとめた<アプリケーションのマルチスレッド誤用に基づく分析の詳細>を見てみましょう.
上記の2つの例は、マルチスレッドアプリケーションでは、スレッドが安全に発生したBUGが実は微妙なので、1つの考えが行き届いていないか、認識が深くないため、問題が発生する可能性は防げないことを説明したいだけです.
二、ReHashの代価
上の最初のポイントは主にスレッドのセキュリティについて話しています.次にハッシュテーブルについても話して、消費コストの大きいReHashを深く理解しています.
私たちが普段理解しているハッシュ・テーブルは「空間で時間を変えるデータ構造」です.このように長く言うと、ハッシュ・テーブルが犠牲になったのは空間であり、勝ち取ったのは時間だと直感的に錯覚するかもしれません.
しかし、ReHashのプロセスは実際には空間と時間の二重の重大な損失であり、ソースコードを分析するため、ReHashのプロセスは実際には動的拡張のプロセスであり、ハッシュテーブルの拡張は空間と時間の消費が非常に驚くべき内部操作であることを知っています.
なぜReHashは空間も時間も驚くべき内部操作なのか.
1、ハッシュ構造のコンテナを拡張する場合、ハッシュ内でより大きな配列を再newし、元の配列の内容を新しい配列にコピーし、再ハッシュを行う.
2、newが出てくるこのもっと大きな新しい配列の容量がどれだけ大きいかも学問であり、一般的には、新しい配列の大きさは元の配列の2倍の大きさに近い素数に設定される(.NETではこの素数の生成には一定のテクニックがある).
1と2の点から,ReHashの対価は確かに非常に高いことが分かる.少し前に.NETコンテナの動的拡張に関する記事<解析ソース解析からよく見られるArrayベースのデータ構造動的拡張メカニズムの詳細>をたまたま書いたことがあるが,その中でも.NETのHashTableの拡張メカニズムを簡潔にまとめた.JavaのHashMapソースコードと照らし合わせて,よく知られているReHash手紙を見たネーミングを数えて、もう一度.NETの実装を見てみると、やはり比較があってこそ向上することができます.
我々が普段理解している「空間で時間を変える」とは,ハッシュがO(1)複雑度を有するデータ検索効率を指すが,充填因子の影響を受け,空間オーバーヘッドが通常大きく,空間利用率が高くない.
だから、ハッシュテーブルは読み取り操作が頻繁で、書き込み操作が少ないアプリケーションシーンに適しているとよく言われています.例えば、ハッシュテーブルをキャッシュ容器として、私の心には戚戚戚があります.
最後に、「この問題をSunに報告した人がいますが、Sunはこれが問題だとは思いません.HashMapはもともと合併をサポートしていないからです.合併するにはConcurrentHashmapを使います...」という言葉を見ました.
実际の开発経験によると、スレッドの安全な容器は本当にスレッドの安全ではなく、ConcurrentHashmapを使うのも初級段阶に入るだけで、当时の日中の景色が无限だったSunを感慨しなければならない.
ネズミおじさんのブログに書いてあるように、もともとは単一スレッドのアプリケーションでしたが、「その後、私たちのプログラムの性能に問題があったので、マルチスレッドになる必要がありました.そこで、マルチスレッドになってからオンラインに着いたら、プログラムが100%CPUを占めていることに気づきました」.
タオバオのエンジニアが暴露した問題を考えると、彼らの技術基礎は一般的にしっかりしていて、彼らさえ間違っていたので、単一スレッドをマルチスレッドに改造するのは想像していたほど簡単ではないと思います.
宝を洗うエンジニアはどうしたのか、単一スレッドをマルチスレッドに変えるのは難しいのか、既存のマルチスレッド技術を応用することにほかならない.ほら、私は非常に強いスレッド安全意識を持っている.同期、デッドロック、競合条件を知っている.lock freeとスレッド安全容器も知っているし、各種スレッドの安全同期構造も知っている.スレッドを出さないで安全なアプリケーション?
実際には、スレッドセキュリティのアプリケーションは、スレッドセキュリティの基礎と開発経験がしっかりしているからといって、必ずしも作成できるわけではありません.
2つの例を挙げてみましょう.
1、スレッド安全容器を使用してインデックスからデータを取る
多くの人が知っているスレッドセキュリティコンテナは、実際に使用するときにBUGが発生しないとは限らない.以下のコードが典型的だ.
static int GetFirstOrDefault(ThreadSafeList list)
{
if (list.Count > 0)
{
return list[0];
}
return 0;
}
上の関数パラメータlistが最初に要素総数1のリストを入力すると、上のコードに何か問題があるのではないでしょうか.
スレッドセキュリティコンテナについては、以前にも「スレッドセキュリティコンテナの実現方法に深く入り込む」という記事をまとめました.スレッドセキュリティコンテナは本当に安全ではありません.問題のあるコードはここから出ています.
2、マルチスレッド操作メールのミス
また、マルチスレッドアプリケーションシーンの分析が正しくない可能性があります.かつてメール送受信プログラムの性能の問題で、私も大胆にアプリケーションを改造したことがあります.変更すると重大なバグが発生しました.
私が心を痛めてまとめた<アプリケーションのマルチスレッド誤用に基づく分析の詳細>を見てみましょう.
上記の2つの例は、マルチスレッドアプリケーションでは、スレッドが安全に発生したBUGが実は微妙なので、1つの考えが行き届いていないか、認識が深くないため、問題が発生する可能性は防げないことを説明したいだけです.
二、ReHashの代価
上の最初のポイントは主にスレッドのセキュリティについて話しています.次にハッシュテーブルについても話して、消費コストの大きいReHashを深く理解しています.
私たちが普段理解しているハッシュ・テーブルは「空間で時間を変えるデータ構造」です.このように長く言うと、ハッシュ・テーブルが犠牲になったのは空間であり、勝ち取ったのは時間だと直感的に錯覚するかもしれません.
しかし、ReHashのプロセスは実際には空間と時間の二重の重大な損失であり、ソースコードを分析するため、ReHashのプロセスは実際には動的拡張のプロセスであり、ハッシュテーブルの拡張は空間と時間の消費が非常に驚くべき内部操作であることを知っています.
なぜReHashは空間も時間も驚くべき内部操作なのか.
1、ハッシュ構造のコンテナを拡張する場合、ハッシュ内でより大きな配列を再newし、元の配列の内容を新しい配列にコピーし、再ハッシュを行う.
2、newが出てくるこのもっと大きな新しい配列の容量がどれだけ大きいかも学問であり、一般的には、新しい配列の大きさは元の配列の2倍の大きさに近い素数に設定される(.NETではこの素数の生成には一定のテクニックがある).
1と2の点から,ReHashの対価は確かに非常に高いことが分かる.少し前に.NETコンテナの動的拡張に関する記事<解析ソース解析からよく見られるArrayベースのデータ構造動的拡張メカニズムの詳細>をたまたま書いたことがあるが,その中でも.NETのHashTableの拡張メカニズムを簡潔にまとめた.JavaのHashMapソースコードと照らし合わせて,よく知られているReHash手紙を見たネーミングを数えて、もう一度.NETの実装を見てみると、やはり比較があってこそ向上することができます.
我々が普段理解している「空間で時間を変える」とは,ハッシュがO(1)複雑度を有するデータ検索効率を指すが,充填因子の影響を受け,空間オーバーヘッドが通常大きく,空間利用率が高くない.
だから、ハッシュテーブルは読み取り操作が頻繁で、書き込み操作が少ないアプリケーションシーンに適しているとよく言われています.例えば、ハッシュテーブルをキャッシュ容器として、私の心には戚戚戚があります.
最後に、「この問題をSunに報告した人がいますが、Sunはこれが問題だとは思いません.HashMapはもともと合併をサポートしていないからです.合併するにはConcurrentHashmapを使います...」という言葉を見ました.
実际の开発経験によると、スレッドの安全な容器は本当にスレッドの安全ではなく、ConcurrentHashmapを使うのも初級段阶に入るだけで、当时の日中の景色が无限だったSunを感慨しなければならない.