2011-02-05 6 views
2

Processのマルチスレッドワーカープールに関するJavaプログラムを作成しています。 Processクラスの各インスタンスは、いくつかの作業を行うために追加のスレッドを1つ生成する必要があります。しかし、そのスレッドは、インスタンス自体によって生成され、他の誰も生成しないでください。残念ながらRunnable.runは 'public'なので、私は実際に何かのトリックをせずにこれを強制することはできません。Java:私的に 'Runnable'クラスで 'run'を呼び出しています

  1. 実装にこのRunnable
  2. Processで書き込みを実装します:

コード:もちろん

class Process implements Runnable { 

    private boolean threadkey = false; 

    public void run() { 

     synchronized(threadkey) { 

      // is someone wrongly calling 'run'? 
      if(!threadkey) 
       return; 

      /* switch off threadkey to make sure 
      it cannot be called meaningfully again */ 
      threadkey = false; 
     } 
     /* continue processing 
     * 
     */ 
     return; 
    } 

を、ここで

は、私が使用する予定のトリックがありますにしたいときに今私がする必要があるすべて正当には、電話をかける前に「スレッドキー」(プライベート)をオンに切り替えることです。

エレガント?か否か?それとも良い方法がありますか?あるいは、私はこれを強制することに気をつけてはならないし、「実行」を呼び出さないことを説明するきちんとした小さなコメントを書くべきですか?

「実行中」を実行する必要があるクラス内から「実行」を呼び出す人もいますか?

答えて

10

Runnableのメソッドが公開されているのは間違いありませんが、他の人が呼び出さないようにするには、Runnableの実装全体をパッケージプライベートクラスまたはプライベート内部クラスにすることです。この方法では、publicrunメソッドがありますが、カスタムクラス以外のコードではRunnableオブジェクトをインスタンス化できません。クラスにも参照を渡さないと、クライアントはRunnableへのアクセス権を持たないため、runを呼び出すことはできません。つまり、RunnableクラスをProcessクラスに実装しないでください。代わりに実際にRunnableを実装する別のクラスを作成し、Processにアクセスできる唯一のクラスにします。

このアプローチは、他のコードが実行時ではなくコンパイル時にrunを呼び出すのを防ぐので、提案した方法よりも洗練されています。特に、上で説明したrunメソッドを呼び出すコードがあれば、それは正常にコンパイルされ、実行時には失敗します。問題は、コードがコンパイルされますが、は決してが正しく動作することです。 Runnableにアクセスできないということは、誰かが実行しようとすると、コンパイル時にエラーが発生し、デザインを再考する必要があることを意味します。つまり、コンパイラはエラーが発生する前にそれを検出します。

一般に、ランダムコードがインターフェイスで宣言されているためにパブリックでなければならないクラスのメソッドを呼び出さないようにしたい場合は、クラス全体のアクセス指定を変更してクライアントがそれを参照しないでください。

6

あなたはこのようRunnableの匿名の内部クラスを使用することができます。

private void spawnThread() { 
    Thread t = new Thread(new Runnable(){ 
      public void run(){ 
      // do something 
      } 
    } 
    t.start(); 
} 

そしてspawnThread()は唯一それがプライベートであるとしてクラス内から呼び出すことができます。もはやそれゆえできRunnableを実装して)

public class Process { 

    private Thread extraThread = null; 

    private void run() { 
     // Do you thing 
    } 

    public synchronized void spawnExtraThread() { 
    if(extraThread != null) 
     return; // Do nothing an extra thread was already spwaned 
    extraThread = new Thread() { 
     public void run() { Process.this.run(); } 
    }; 
    extraThread.start(); 
    } 
} 

主なポイントは、そのクラスのプロセス(ある:

1

あなたは()メソッドのプライベートを実行していないことができ、そしてそれにアクセスするために(Runnableを実装する)の内部クラスを使用しますもはやスレッドに変換されません。もちろん、スレッドの数の制限をサポートするようにこの設計を拡張します(extraThreadフィールドをスレッドの配列に変更するだけです)。

関連する問題