2

私は、シリアルポートを使用するC ++プログラム(より正確には、Borlandの「コンポーネント」)をJavaに「変換」しています。そのプログラムはスレッドを使用してシリアルポートをリッスンし、指定された「イベント文字」の1つ(キャリッジリターン、ACK、NACKなど)を受信したとき、またはユーザーが定義した数の文字を受け取ります。

Javaで変換しようとしているときに、スレッドについて少し学び、半分機能するようにしました。リスニングスレッドからメインスレッドにイベントを発生させる方法をまだ理解する必要があります...そして、ユーザーが閉じたり、再開したり、変更したりできるため、エグゼキューターの存在を学びました。これは正しい方法のようです。ポートを複数回使用し、毎回新しいスレッドを作成することは悪い習慣のようです。

したがって、Javaの並行性の海で何日も苦労する前に、「生の」スレッドに多くの作業を費やした後、アドバイスと、おそらく少しのサンプルを求めます。

シリアルリスナーを作成するには、どの種類のオブジェクト(さまざまな種類のエグゼキューターがあると思います)を使用する必要がありますか。

  • 受信したchars配列を渡すためにメインスレッドにイベントをスローすることができます
  • 一時停止して再起動できます(一時停止中に別の入力ストリームを指すことができます...つまり、一時停止中にそのメソッドの一部を呼び出すことができます)
  • 不要な場合は破棄されます(ユーザーは代わりにソケットを使用することを選択できるため、リスナーは不要になります)

?これらのポイントのいくつかが選択するオブジェクトに依存しているかどうかは本当にわかりません。そのため、もう一度すべてをやり直すのを避けるために、すべてをリストしました。

ありがとう。

4

2 に答える 2

2

他のスレッドからイベントを受信する必要があるメイン スレッドがある場合 (サーバー ソケットのように)、ブロッキング キューが解決策になる場合があります。メイン スレッドはtakeLastループ内で を呼び出すことができます。これにより、他のスレッドが を呼び出すまで中断さputFirstれ、同じキューに対して取得する値が提供されます。( SynchronousQueueは、メイン スレッドの準備が整うまで、または代わりに ArrayBlockingQueueが指定されたサイズのキューをサポートするまで、提供スレッドを停止します)。

このような設定では、メイン スレッドを GUI スレッドにすることはできません。ラベルやボタンなどのインターフェイス コンポーネントに触れる必要がある場合は、invokeAndWaitを使用します。

 final BlockingQueue q = new ArrayBlockingQueue(3); 

 new Thread() {
    public void run() {
       while (have_some_messages()) { 
         q.putFirst("Hey!");
       }
    }
 }.start();

 new Thread() {
    public void run() {
       while (also_have_some_messages()) { 
         q.putFirst("Boo!");
       }
    }
 }.start();

 // Main thread will print both Hey and Boo:
 while (must_keep_running()) {
   Object serveIt = q.takeLast();
   System.out.println(serveIt);
 }

メイン スレッドが Swing スレッド (Swing コントロールを持つ JFrame と言う) の場合、そこにボタンを追加してサービス スレッドを開始します。

Runnable service = new Runnable() {
  public void run() {
    try {
      while (must_keep_running()) {
    Object serveIt = q.takeLast();
    System.out.println(serveIt);
  }
} finally {
// Re-enable the start button when the service thread exits:
  SwingUtilities.invokeLater(new Runnable() {
        public void run() {
          bStart.setEnabled(true);
            }
          });
        };
      }
    };

 JButton bStart = new JButton("Start ..");
 bStart.addActionListener(new ActionListener() {
    public void actionPerformed(ActionEvent e) {
         new Thread(service).start();
         bStart.setEnabled(false);
      }    
    }
 });
于 2013-01-30T11:44:48.147 に答える
-1

おそらくいくつかの静的な(同期された!)アクセサーを備えたシングルトンに基づいて、ポートリースニングスレッドを作成します。

あなたの場合のスレッド間の通信に適したインターフェースは、リスナー/オブザーバー パターンです。問題を解決するのに十分な汎用性があるはずです。

あなたは Java の初心者なので、1 つのヒント: スレッドなしで開始し、ノンブロッキング IO のみを使用してください。次に、すべてが正常に機能した後でのみ、複数のスレッドの使用を検討してください。また、パフォーマンスに問題がある場合にのみ実行してください。

于 2013-01-30T11:21:14.500 に答える