2011-10-14 55 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