Go to Contents Go to Java Page

JavaOne 2002 in SF Report

 
 

6/13 最終日

 
 

今日で JavaOne も終わりです。去年より 1 日短いのですが、このくらいの方がいいかもしれません。

今日の General Session は、Sun Microsystems の CEO Scott McNealy です。後半に Jonathan Schwartz が再登場して、Motolora や Nokia といった Mobile 系の企業の方とパネルを行いましたが、おまけみたいなもんです。

また、今日は BOF はなくて Technical Session だけです。それも、4 時には終わってしまいます。

パビリオンはすでに終了していて片付けをしています。刻々と最後の時間が迫ってきているわけです。

それでは、本日のレポートです。

 

 
 

General Session

 
 
John Gage

John Gage

そういえば、今年の John Gage は少し違います。なにが違うって、服装が違います ^^;;

いつもの黒のポロシャツにチノだったのですが、今年は黒のポロシャツっぽい襟のある長袖のシャツに、黒のパンツです。心境の変化でもあったのでしょうか。

もう 1 つついでですが、プログラムには Rob Gingell も MC になっているのですが、どうして登場しなかったのでしょう。会場にいるのを見たので、いないわけではないのですが、これも謎です。

 

Scott McNealy

今年の JavaOne はいつもよりテクニカルにしてあるといってました。事実そうだと思います。彼が登場する前に John Gage が Concurrency Utilities のセッションがまた行われることをいっていたのですが、Scot McNealy は次分も時間があったら参加するつもりだったと冗談をいってました。

彼の話題はまずソフトウェアの区分からでした。どんな風に分けたかというと

  • Plastic-Wrapped Software
  • Rack-Wrapped Software
  • Gift-Wrapped Software
  • Unwrapped Software

です。Plastic-Wrapped は携帯や PDA のようなプラスティックでできたアプライアンスに載るソフトウェアです。ここでのソフトウェアはコンパクトでなければなりません。こんなところに重たい OS が載せてあるものを誰が使いたがるだろうと、暗に Microsoft を皮肉っているのも彼ならばです。

次の Rack-Wrapped はいわゆるサーバ系のソフトウェアです。Sun はずっとこの分野をメインにしていました。Gift-Wrapped はサーバ系ではありますが、Amazon などのコンシュマー系のソフトウェアです。

最後に残った Unwrapped はオープンソースのソフトウェアです。どこにも属さずに、ボランティアで開発されていくためです。Unwrapped が非常に重要であると述べてました。

diploma
Duke's Choice Award

Verizon のデモをはさんで、次に行ったのが Java と .NET の比較です。学生の成績比較のような感じで行いました。

いろいろな点から比較を行っています。例えば "Choice" では、Java が様々なベンダやフリーのツールなどあることから A、.NET は Microsoft だけなので C です。

最後には Java は優秀な成績で合格、.NET は補修が必要でした。まぁ、どっちにしても Java を悪くするはずないのですが...

最後に Duke's Choice Awards を発表しました。Java で貢献した企業や団体を選出しています。それぞれ、XXX 賞と名前がついているのですが、メモをし忘れたので、選出されたものだけを示しておきます。

  • Mars Rover
  • NYPD: Criminal analysis & report system
  • Getty Museum: Interactive Guide
  • NHL.com: Realtime scoring with Java-powered alerts
  • HBO: Digital Repository
  • Pogo.com: Java Games
  • Java Card & Sun RAY
  • Brazil Medical System
  • Jentro: Automative voice navigation via cell phone
  • University of Calgary: Visualization cave
  • Nokia: Nokia 6800

HBO にだけ Duke のトロフィーを渡していました。Nokia の人とかもいたのにどうして渡さなかったのでしょう?

 

 
 

Technical Session

 
 

今日、聴講したのは 2 つのセッションです。

  • TS-2125 Advanced OpenGL for the Java Platform
  • TS-3708 Concurrency Utilities - Mulitthreading Made Easy

Concurrency Utilities は初日に行われたセッションですが、私も締め出されたように、非常に多くの人が聴講できませんでした。それで、今日リクエストセッションとしてもう 1 回、行われることになりました。残念ながら、Doug Lea は NY に帰ってしまったので、代わりに Brian Goetz が講演しました。

TS-2125 Advanced OpenGL for the Java Platform

今年の JavaOne のトピックの 1 つに Game があることは先に述べたとおりです。特に Desktop の Game です。ということは Java のパフォーマンスも Game を作るに十分なほどになったわけです。

以前から 2D のゲームには Java が使用されていましたが、3D のゲームはなかなか難しかったと思います。Java で 3D というと Java3D がありますが、シーングラフがベースになっていることから分かるようにかなり高レベルのライブラリです。これを Game に使用するのは、パフォーマンス的に難しい面があります。そこで、もっと低レベルのライブラリということで OpenGL を直接使用するライブラリが登場するわけです。

セッションでは Java - OpenGL バインディングライブラリのいくつかを紹介しました。紹介されたものを次に示します。

  • OpenGL for Java
  • Lightweight Java Game Library
  • Magician
  • Jungle
  • GlueGen

そして、Jungle を使用して、OpenGL のレンダリング手法を Java からコントロールするデモを行いました。最近の 3D の傾向として、Configurability から Programability へと変化してきます。特に、NVIDIA の Cg や DirectX9 の HLSL などのシェーダー用の言語が登場したことでこの傾向が加速しています。デモは

  1. Fixed-function Pipeline
  2. Programmable Pipeline
  3. Vertex Shader
  4. Fragment Shader
  5. Vertex Shader + Fragment Shader

に関して行われました。デモに使用したのは Virtual Fishtank や NVIDIA の Phong Lightnig などです。すべて、Java からコントロールされているものです。

 

TS-3708 Concurrency Utilities - Multithreading Made Easy

Doug Lea を直接拝めなかったのは残念ですが、とりあえず聴講できたのでよかったです。

Concurrency Utilities は Tiger に含まれる、マルチスレッド用のユーティリティです。もともと Doug Lea が作成していたものをベースに、JSR-166 で標準化されるという経緯をたどっています。

パッケージは java.util.concurrent になります。また、util のサブパッケージが 1 つ増えました。util の下はどんどん増えていきます。

Concurrency Utilities では次のような API を提供します。

  • Executor, Thread Pool など
  • Queue, BlockingQueues
  • Timing
  • Lock, Condition
  • 同期化 Semaphore, Barrie など
  • Atomic Variable
  • その他

まず Executor ですが、Thread の代わりに非同期に処理を実行するインタフェースです。実際にはユーティリティクラスの Executors から実行することが多いようです。Executor が扱えるのは Runnable インタフェースと新しく導入された Callable インタフェースです。

Callable インタフェースは Runnable の代わりに使うことができますが、どちらかというと処理を中心にしたものです。Callable で実行した結果は Futures インタフェースの get メソッドを使用して取り出すことができます。

class ImageRenderer {
    Image render(byte[] raw) {
        ...
    }
 
class App {
    ...
    Executor executor = ... ;  // any executor
    ImageRenderer renderer = new ImageRenderer();
 
    public void display(final byte[] rawImage) {
        try {
            Future img = Executorss.invoke(executor,
                           new Callable() {
                               public Object call() {
                                   return render.render(rawImage);
                               }
                           });
 
            drawBorders(); // do other things ...
            drawCaption(); // ... while executing
 
            drawImage((Image)(img.get()));
        } catch (Exception ex) {
            cleanip();
            return;
        }
    }
}

Thread Pool を待ち望んでいた人は多いのではないでしょうか。こんな風に使います。

class WebService {
    public static void main(Sring[] args) {
        Executor pool = Executors.newFixedThreadPool(7);
        ServerSocket socket = new ServerSocket(9999);
 
        for (;;) {
            final Socket connection = socket.accept();
            pool.execute(new Runnable() {
                public void run() {
                    new Handler().process(connection);
                }
            });
        }
    }
}
 
class Handler {
    void process(Socket s) {
        ...
    }
}

この例では 7 つのスレッドをプールしています。

Queue インタフェースは次のように定義されています。

package java.util

 
public interface Queue exends Collection {
    boolean add(Object x);
    Object poll();
    Object remove() throws NoSuchElementException;
    Object peek();
    Object element() throws NoSuchElementException;

このインタフェースを実装したクラスは

  • java.util.LinkedList (not Thread-safe)
  • java.util.PrioriyQueue (not Thread-safe)
  • java.util.concurrent.LinkedQueue (Thread-safe, non-blocking)

また、Queue インタフェースを派生させた BlockingQueue インタフェースも提供されます。多分、パッケージは java.util.concurrent だと思うのですが、言及しませんでした。

public interface BlockingQueue extends Queue {
    voic put(Object x) thrwos InterruptedException;
    boolean offer(Object x, long timeout,
                  TimeUnit unit) throws InterruptedException;
    Object take() throws InterruptedException;
    Object poll(loing timeout,
                TimeUnit unit) throws InterruptedException;
}

BlockingQueue を使用すれば wait - notify を使用せずに Producer - Consumer モデルを簡単に実装できます。例えばこんな感じです。

コード中の青字の部分が Producer、緑が BlockingQueue、赤が Consumer になります。また、この例では BlockingQueue のコンクリートクラスとして LinkedBlockingQueue クラスを使用しています。

class LoggedService {
    final BlockingQueue msgQ = new LinkedBlockingQueue();
    
    public void serve() throws InterruptedException {
        // ... perform service ...
        String status = ...;
        msgQ.put(status);
    }
 
    public LoggedService() { // Start background thread
        Runnable longr = new Runnable() {
            public void run() {
                try {
                    for (;;) {
                        System.out.println(msgQ.take());
                    }
                } catch (InterruptedException ex) {
                    ...
                }
            }
        };
        Executors.newSingleThreadExecutor().execute(logr);
    }
}

BlockingQueue インタフェースで使用されている TimeUnit クラスはナノ秒までサポートした時間を表わすクラスです。このクラスは java.util.Date クラスや System#currentTimeMillis() メソッドとは関係がありません。

次は Lock です。

public interface Lock {
    void lock();
    void lockInterruptibly();
    boolean tryLock();
    boolean tryLock(long timeout,
                    TimeUnit unit) throws InterruptedException;
    void unlock();
    Condition newCondition();
}

コンクリートクラスとして ReentrantLock が提供されています。Lock のサンプルを次に示します。

class ParicleUsingLock {
    private int x, y;
    private final Random rng = new Random();
    private final Lock lock = new ReentrantLock();
  
    public void move() throws InterruptedException {
        lock.lockInterruptibly(); // allow cancellation
        try {
            x += rng.nextInt(3) -1;
            y += rng.nextInt(3) -1;
        } finally {
            lock.unlock();
        }
    }
 
    public void draw(Graphics g) {
        int lx, ly;
        lock.lock(); // no interrupts - AWT Event Thread
        try {
            lx = x;
            ly = y;
        } finally {
            lock.unlock();
        }
 
        g.drawRect(lx, ly, 10, 10);
    }
 
    ...
}

入出力の時に使用される ReadWriteLock インタフェースもあります。

同期化を行うクラス群は特定の場面で使われるようなクラスを集めたものです。次のようなクラスが提供されています。

  • Semaphore
  • FifoSemaphore
  • CountDownLatch
  • CyclicBarrier
  • Exchanger

Semaphore は許可を持ったオブジェクトみなすことができます。はじめに許可を許す数を設定しておきます。acuire で許可を取得し (許可が取得するまでブロックします)、release で開放します。

通常は Lock と一緒に使用されます。次の例はリソースプールの例です。

class ResourcePool {
    Semaphore available = new Semaphore(N);
    Object[] items = ...;
 
    public Object getItem() throws InterruptedException {
        available.acquire();
        return nextAvailable();
    }
 
    public void returnItem(Object x) {
        if (unmark(x)) {
            available.release();
        }
    }
 
    synchronized Object nextAvailable();
    synchronized boolean unmark(Object x);
}

その他に Atomic やスレッドセーフのコレクション (ConncurrentHashMap や CopyOnWriteArrayList などがあります。また、リソースの消費を防ぐために ThreadLocal#remove メソッドが新たに導入されています。

 

 
 

おまけ

 
 

今日の General Session のオープニングはアフリカ系の音楽を演奏するバンドでした。純粋にアフリンカンミュージックではないのですが、まぁそんなことはどうでもいいです。

何がすごいって、パーカッションです。和楽器の鼓のように、太鼓の紐を締めたり緩めたりすることで音程が変えられるのですが、とても器用に音程を変えるのです。はじめ、エレクトリックタムがあるのかと思ったぐらいです。どこを探しても、普通のドラムとパーカッションしかないのです。結構、ビックリです。

ところで、JavaOne は常に大スクリーンにいろいろ映しています。General Session などは誰を映せばいいかすぐ分かると思うのでカメラマンも楽なのでしょうが、バンドの映像は全然ダメ。

誰がリードとっているかをまったく理解していないのです、ギターがリードを取っているときにベースを撮ってみたり、パーカッションのパートでホーンセクション撮ってみたり。もうちょっと勉強してきなさいという感じです。

来年会いましょう

何はともあれ、今年の JavaOne は終わってしまいました。今年は Scott McNealy がいっていたように、開発者向けになって、原点回帰をしたように思います。プログラムを見てもビジネスセッションが非常に減っています。

この傾向は私にとっては非常に望ましいものです。来年もあまり浮かれたお祭り騒ぎの JavaOne よりも、今年の延長線上であることを切に願っています。

来年は 6/28 から 7/1 です。

 

(2003.6.13)

 
 
Go to Contents Go to Java Page