Last active
February 23, 2019 10:44
-
-
Save martin640/4fe5cd6221233dd82230c8818ea92d95 to your computer and use it in GitHub Desktop.
Simple looper for multiple synchronized operations in Java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package sk.gocrafterlp.networkconnections.handler; | |
import java.util.ArrayList; | |
import java.util.List; | |
public class LooperCompat { | |
private final List<Message> messageQueue; | |
private boolean running, exiting; | |
private Thread thread; | |
public LooperCompat() { | |
messageQueue = new ArrayList<>(); | |
running = true; | |
thread = new Thread(new Runnable() { | |
@Override | |
public void run() { | |
while (running) { | |
loop(); | |
try { | |
Thread.sleep(10); | |
} catch (InterruptedException e) { | |
e.printStackTrace(); | |
} | |
} | |
} | |
}); | |
thread.start(); | |
} | |
private void loop() { | |
Message message = null; | |
MessageGetter: synchronized (messageQueue) { | |
if (exiting && messageQueue.isEmpty()) { | |
running = false; | |
return; | |
} | |
for (int i = 0; i < messageQueue.size(); i++) { | |
Message next = messageQueue.get(i); | |
if (exiting) { | |
if (next.time > 0) { // cancel delayed message | |
messageQueue.remove(i); | |
return; | |
} | |
} | |
if (next.time == 0 || System.currentTimeMillis() >= next.time) { | |
message = next; | |
break MessageGetter; | |
} | |
} | |
} | |
if (message == null) return; | |
Runnable runnable = message.getRunnable(); | |
Object tag = message.getTag(); | |
if (runnable != null) runnable.run(); | |
synchronized (messageQueue) { | |
messageQueue.remove(message); | |
} | |
} | |
/** | |
* Method will move looper into exiting state so all instant messages will be finished | |
*/ | |
public void stop() { | |
exiting = true; | |
} | |
public boolean postDelayed(Runnable runnable, long delay) { | |
if (delay < 0) throw new IllegalArgumentException("Negative delay"); | |
if (exiting) return false; | |
synchronized (messageQueue) { | |
Message message = new Message(runnable, null); | |
message.time = System.currentTimeMillis() + delay; | |
messageQueue.add(message); | |
} | |
return true; | |
} | |
public boolean post(Runnable runnable) { | |
if (exiting) return false; | |
synchronized (messageQueue) { | |
messageQueue.add(new Message(runnable, null)); | |
} | |
return true; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package sk.gocrafterlp.networkconnections.handler; | |
class Message { | |
Runnable runnable; | |
Object tag; | |
long time; | |
Message(Runnable runnable, Object tag) { | |
this.runnable = runnable; | |
this.tag = tag; | |
} | |
Runnable getRunnable() { | |
return runnable; | |
} | |
Object getTag() { | |
return tag; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment