I have a android application with lots of buttons. If a button is pressed it sends a short cmd to a server via a socket.
Currently, when a button is pressed this adds a cmd to a list. I have a worker thread that constantly checks the list for cmds and if it finds one opens a socket and sends the cmd.
This is not very efficient as the worker thread is constantly running. What would be the best way to improve this?
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)开发者_Go百科;
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();
}
}
}
The UI activity adds a cmd by calling Arduino.sendCmd("cmdName"); The cmds need to be sent as quickly as possible so a sleep in the loop is no good. Any ideas or examples would be appreciated.
Use a wait/notify pattern. Put the sender on a thread with the list. Whenever there is something to write to the worker thread, have the writer add the command, and then notify the thread. If the thread is already awake, the notify will do nothing.
Here is a quick example, clearly the mechanism you will use to start the writing thread will be different.
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)
}
}
}
}
}
精彩评论