2011-10-14 53 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,找到了更簡單的解決方案。感謝您指點我正確的方向。 private static BlockingQueue cmdsToSend = new LinkedBlockingQueue ();然後,而不是使用cmdsToSend.poll()你可以使用cmdsToSend.take(); – smee204

+0

不錯!隨時回答並接受你自己的問題和有用的信息,因爲我實際上沒有給你你需要的東西。 – Noah