随筆:「並行処理」

by ご近所のきよきよ


 
 「Java並行処理プログラミング(ブライアン・ゲーツ他著 ソフトバンク)」を夢中で読みました。Javaの新しい並行処理機能が分かったし、スレッドセーフなプログラミング技法も習得できたように感じるので、すごく啓発されました。とくにスレッドのスケジュールが明晰でしたね。求めていたものです。ただ、スレッドセーフなプログラミングを実現したり、デッドロックの回避が難しいなどの煩雑な技術があって、並行処理は難しいかなと感じました。これはJavaひいては全てのソフトウェアでの問題なんだろうなということで、これは何とかしなくては・・・と思いました。
 
 スレッドセーフの簡易的な実現とデッドロックの回避のための技術を考えてみました。以下にそれを記していきます。数学的な厳密に欠けますが、そこは読者にお任せ致します。
 
 オブジェクト(クラス)は入れ子になっていることに注目しました。物理的配置もさることながら、いや確かに物理的には入れ子になくとも、処理時間を追っていくと処理の動きはオブジェクトからオブジェクトへと深くなっていき、そこから段々に飛び越し無く元のオブジェクトに戻っていきます。まっ、確かに飛び越しで戻るプログラミング技術もありますが、その場合でも仮想的に順繰りに戻っていくと考えることはできます。すべからく、入れ子構造という枠組みで議論できるということです。
 であるならば、この時間的入れ子を仮想オブジェクトと考えて、このオブジェクト内は1つのスレッドしか占有できないとするのです。内部に3つ仮想オブジェクトがあれば、スレッドを追加で2つ興し、自分とそれぞれのスレッドをその仮想オブジェクトに通すようにする。
 これだけで、並行処理でのスレッドセーフとデッドロック回避が実現します。すなわち、
(1)仮想オブジェクトのロックをオブジェクトの入れ子パスを基本に掛けること
 仮想オブジェクトの入り口で自分のID(オブジェクトにはシステム一意の識別子が振られるのが普通)を今までのID列に負荷してロックを掛けます。戻るときにロックをはずす。
 仮想オブジェクトを汚す処理と汚さない処理でロックを分けると、汚さないスレッド群は1つの仮想オブジェクトに共存できるわけで、そのことを考慮した並列処理の実現は望ましいものです。ちなみに、汚す汚さないはソースプログラムのコンパイル時に解析できます。
(2)予約ロックの実現
 この(1)でロックを仮想オブジェクトの入り口で掛けるとしましたが、デッドロックの回避には予約ロックがいいと思います。つまり、仮想オブジェクトの入り口でロックを掛けるのは、そのオブジェクト内でさわるサブ仮想オブジェクト群のロックをあらかじめ一気に取得するという技法です。こうすれば、仮想オブジェクトを構成する物理オブジェクトのロックがデッドロックを回避して行えます。デッドロックしようとすればウェイトさせることも可能です。
 
 ということで、これなら大規模平行処理プログラムも安心してつくれる(ほとんどコンパイラの作業として吸収できるから、syncronizedという命令はいらなくなります)ようになります。・・・たぶん。ひょっとして、クラス全体をsyncronizedにした感じになるのでしょうか。それでもロック機構は簡単になるからスピードアップにはなるでしょう。オブジェクトの属性としてロックIDを保持しておくだけの軽快さだからです。
 
 
 

おわり