2011-10-14 15 views
0

私は多くのボタンを持つAndroidアプリケーションを持っています。ボタンを押すと、ソケットを介して短いcmdがサーバに送信されます。androidアプリケーションからソケットを介して小さなcmdsを送信

現在、ボタンを押すと、リストにcmdが追加されます。 私は常にcmdsのリストをチェックするワーカースレッドを持っていて、見つかったらソケットを開いてcmdを送信します。

ワーカースレッドが絶えず実行されているので、これはあまり効率的ではありません。これを改善する最善の方法は何でしょうか?

public class Arduino implements Runnable{ 

private static PrintWriter arduinoOutput; 
private static Socket ss; 
private static Queue<String> cmdsToSend=new LinkedList<String>(); 
private static String cmd; 

public void run(){ 
    while(true){ 
     if(!cmdsToSend.isEmpty()){ 
      cmd = cmdsToSend.poll(); 
      System.out.println("send:"+cmd); 
      if(connect()){ 
       arduinoOutput.println(cmd); 
       disconnect(); 
      } 
     } 
    } 
} 

public static void sendCmd(String newcmd){ 
    cmdsToSend.add(newcmd); 
} 

private static boolean connect(){ 
    try { 
     ss = new Socket(); 
     InetAddress addr = InetAddress.getByName("192.168.1.8"); 
     int port = 23; 
     SocketAddress sockaddr = new InetSocketAddress(addr, port); 
     ss.connect(sockaddr, 2000); 
     arduinoOutput = new PrintWriter(ss.getOutputStream(),true); //Autoflush 
     return true; 
    } catch (UnknownHostException e) { 
     return false; 
    } catch (IOException e) { 
     return false; 
    } 
} 

private static void disconnect(){ 
    arduinoOutput.close(); 
    try { 
     ss.close(); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 
} 

}

UIアクティビティがArduino.sendCmd( "cmdNameという")を呼び出すことで、CMDを付加します。できるだけ早くcmdsを送る必要がありますので、ループ内の睡眠は悪いです。 アイデアや例があれば幸いです。

答えて

0

待機/通知パターンを使用します。送信者をリストのスレッドに入れます。ワーカースレッドに書き込むものがあれば、ライターにコマンドを追加させてから、スレッドに通知してください。スレッドがすでに起きている場合、通知は何も行いません。

これは簡単な例ですが、明らかに書き込みスレッドを開始するためのメカニズムは異なります。

import java.util.LinkedList; 
import java.util.Queue; 
import java.util.concurrent.ThreadFactory; 

public class Notifier 
{ 
    public static void main(String args[]) 
    { 
     Writer writingThread = new Writer(); 
     writingThread.addToQueue("Command 0"); 
     ThreadFactory.submitInSingleThread(writingThread); 

     for (int i = 1; i < 1000; i++) 
     { 
      writingThread.addToQueue("Command " + i); 
      writingThread.notify(); 
     } 
    } 

    static class Writer implements Runnable 
    { 
     private static Queue<String> cmdsToSend = new LinkedList<String>(); 

     public void addToQueue(String cmd) 
     { 
      cmdsToSend.add(cmd); 
     } 

     @Override 
     public void run() 
     { 
      while(true) 
      { 
       if(!cmdsToSend.isEmpty()) 
       { 
        String cmd = cmdsToSend.poll(); 
        System.out.println("send:" + cmd); 
        if(connect()) 
        { 
         arduinoOutput.println(cmd); 
         disconnect(); 
        } 
       } 

       synchronized(this) 
       { 
        wait(); //Can add a timer (100ms, for example) 
       } 
      } 
     } 
    } 
} 
+0

この待機/通知パターンを調べているうちに、QueueをBlockingQueueに変更すると簡単な解決策が見つかりました。正しい方向に私を指してくれてありがとう。プライベート静的BlockingQueue cmdsToSend = new LinkedBlockingQueue (); cmdsToSend.poll()を使用する代わりに、cmdsToSend.take()を使用できます。 – smee204

+0

ニース!私が実際にあなたに必要なものを与えなかったので、お気軽にあなた自身の質問に答えてください。 – Noah

関連する問題