1

バックグラウンドで実行されているスレッドから、そのオブジェクトのロックのために wait() でスレッドを目覚めさせるために、クラス A にその内部で notify() を呼び出す方法ありますか?

ありがとう。

編集:

不要なコードは無視してください。私が実際にそれをどのように実装したかをお見せしたかったのです。

Messenger はシリアル化されたオブジェクトです。

スレッド「ServerHandler」が呼び出されます bufferImpObject.put(<Messenger Obj>, <ServerHandler instance>, <socket instance>)

public class BufferImp {
    private Messenger[] requests;
    public  static int req_size;
    public static int req_count;


     Socket s;
     Messenger msg;
     InputStream is;
     ObjectInputStream ois;
     OutputStream os;
     ObjectOutputStream oos;



    public BufferImp(int size) {
        this.req_size = size;
        this.req_count = 0;
        requests = new Messenger[size];

    }



     class CheckWaitThread extends Thread{
        Thread t;
        String s;
        Socket incoming_socket;



        CheckWaitThread(String s, Thread t, Socket incoming_socket){
            this.t = t;
            this.s = s;
            this.incoming_socket = incoming_socket;


        }
        @Override
        public void run(){
            try {
               // I want to keep on checking till slots are FREE
               // IF FREE, call notify() of BufferImp to get back WAITING (inactive) ServerHandler thread
               if(t.getState().equals(State.WAITING)){ 
                              os = incoming_socket.getOutputStream();
                              AppendableObjectOutputStream oosa = new AppendableObjectOutputStream(os);
                              oosa.writeObject(new Messenger("bufferFull", null, "true"));


                }
                t.join();
            } catch (IOException ex) {
                Logger.getLogger(BufferImp.class.getName()).log(Level.SEVERE, null, ex);
            } catch (InterruptedException ex) {
                Logger.getLogger(BufferImp.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }

    // insert incoming Message objects into "requests" queue 
    public synchronized boolean put(Messenger o, Thread t, Socket s) throws InterruptedException {


        while(req_size == req_count) {
            CheckWaitThread cw = new CheckWaitThread("<----------CheckWaitThread----------->", t, s);
            cw.start();
            wait(); 


        }

        // these parts need to be executed when notify() is called.
        requests[cur_req_in] = o;
        cur_req_in = (cur_req_in + 1) % req_size;
        req_count++;
        notifyAll();
        Messenger msg = (Messenger) o;


        return true;
    }




}
4

2 に答える 2

5

あなたの質問に対する簡単な答えはノーです。

あなたの質問は非常に不明確ですが、これがあなたが求めていることだと思います:

  • クラス A が拡張ThreadRunnableれ、スレッドが何らかのAオブジェクトをターゲットとして実行されます。それを AThread と呼びます。

  • そのスレッドは A オブジェクトのロックを所有しており、他のスレッド (OThread) はそれを待機しています。

  • 他のスレッド (BgThread) が待機中のスレッドをウェイクアップできるようにします。

重要な点は、 notifyは lockを所有するスレッドからのみ呼び出すことができるということです。そのため、バックグラウンド スレッドがロックを所有していない場合、通知を呼び出すことはできません。

編集:

追加したコードを見ると、で待機メカニズムを構築しようとしているようですBufferImprequests容量がいっぱいにCheckWaitThreadなると、受信ソケットに bufferFull メッセージが書き込まれるため、おそらくクライアントはそれ以上の要求の送信を停止します。そして、どういうわけか(他のスレッドがポップしてリクエストを処理しているため)、将来のある時点でマシンが再び回転を開始します。

そんなに頑張る必要はない

  • requests応答を送信して、別のスレッドでコレクションが解放されるのを待つ必要があるのはなぜですか? なんでこのスレから送れないの?

  • requests array自分で管理する代わりに、まさにこの目的を作成したBlockingQueueを見てください。

于 2011-10-09T12:59:11.940 に答える
0

すべてのコードはスレッドで実行され、バックグラウンドとフォアグラウンドの違いは概念的なものです。

notify() を呼び出すには、通知されたオブジェクトをロックするだけです。

于 2011-10-09T13:07:59.117 に答える