I am new to Java and pulling some hair out on the application I'm working on. Here is what I am trying to do.
I have a client / server setup where I use QuickServer as the server. I got that up and running well. It sends and receives commands line by line with "\r"\n" so I have my client in a
public class CommandHandler extends Thread {
public void run() {
while (connected) {
//read and write
if (command.equals("USERNAME")) {
AsynchEventBusSingleton.$().postEvent(new TellParentToGiveUN())
}
...
}
}
My GUI freezes if I do not extend Thread so I presume the CommandHandler needs its own thread. The problem however is the AsyncEventBusSingleton.
public class AsyncEventBusSingleton {
private EventBus ebEventBus = null;
final static AsyncEventBusSingleton aebInstance = new AsyncEventBusSingleton();
public synchronized static AsyncEventBusSingleton $() {
return aebInstance;
}
private AsyncEventBusSingleton() {
ebEventBus = new AsyncEventBus(Executors.newCachedThreadPool());
}
public void registerSubscriber(Object subscriber) {
ebEventBus.register(subscriber);
}
public void unRegisterSubscriber(Object subscriber) {
ebEventBus.unregister(subscriber);
}
public synchronized void postEvent(Object e) {
ebEventBus.post(e);
}
}
When I call this class inside CommandHandler thread none of my other classes on the main thread receive the events. If I remove the "synchronized" keyword some of the events are received/repeated/an error is generated.
Everything seems to work fine if don't throw events from CommandHandler, but rather pass a reference of the class that instantiates the CommandHandler and have it call CommandHandler's methods:
public class ServerConnectionHandler {
private CommandHandler commandhandler;
public void ConnectToServer() {
commandhandler = new CommandHandler(this);
}
public void dispatchServerEvent() {
commandhandler.sendResponse("MyUN");
}
}
public class CommandHandler extends Thread {
private PrintWriter printWriter;
private ServerConnectionHandler serverconnectionhandler;
public sendResponse(String s) {
this.printWriter.println(s);
}
public void run() {
while (connected) {
//read and write
if (command.equals("USERNAME")) {
this.serverconnectionhandler.dispatchServerEvent();
}
...
}
}
What is the best practice for having the client listen for certain commands and dispatching events to respond?
Related
I've a socket connect method in my class that's supposed to be called by only 1 thread at a time. Inside that synchronized method, I've a synchronized block based off an random object. I'm calling the synchronized connect method of my class from an Android service
Problem:
Sometimes the app goes into non responding state if the socketIO connection takes longer to establish connection when the socket URL is not reachable. I've no clue why this is happening.
class MyService extends Service {
public void onStartCommand() {
MyUtilClass.getInstance().init();
MyUtilClass.getInstance().startSomeOSBroadcastListeners();
MyUtilClass.getInstance().connectAsync();
}
}
class MyUtilClass {
private final Object tempObj = new Object();
private MyUtilClass mUtilClass;
public static MyUtilClass getInstance() {
if(mUtilClass == null)
mUtilClass = new MyUtilClass();
return mUtilClass;
}
public void init() {
startListeningSocketIoConnectEvent();
}
public MyUtilClass connectAsync() {
new Thread(new Runnable() {
connect();
}).start();
return this;
}
private synchronized MyUtilClass connect() {
synchronized(tempObj) {
mSocketIO.connect();
tempObject.wait();
}
return this;
}
private void startListeningSocketIoConnectEvent() {
mSocketIO.on(Socket.EVENT_CONNECT, new Emitter.Listener() {
#Override
public void call(Object... args) {
synchronized (mWaitLock) {
tempObj.notifyAll(); //releasing the lock
}
}
});
}
}
The tempObj is only being used for socketIO connection phase afterwards it's not used.
Why does it sometimes go into ANR state? Is this implementation correct?
I have a Processor class which implements Runnable.
The first method
Public Processor implements Runnable{
//"Event" is the name of this queue
PersistentQueue<Event> persistentQueue = new PersistentQueue<>("Event");
//add the Event POJO to the persistentQueue
public void addToQueue(Event, event) {
persistentQueue.add(event);
}
The persistentQueue is to store Event POJO
And the run method
public void run() {
while (true) {
if (!persistentQueue.isEmpty()) {
Event peekEvent = persistantQueue.peek();
sendRequest(peekEvent);
}
}
}
public void sendRequest(Event, event){
// do something to send the event
}
For the first addToQueue method I wrote the test
public class ProcessorTest {
private Event event;
private Processor m_Processor;
#Before
public void setup() throws IOException {
//the Processor class is a singleton
m_Processor = Processor.getProcessor();
event = new Event();
}
#Test
public void test(){
PersistentQueue<Event> persistentQueue = new PersistentQueue<>
("Event");
m_Processor.addToQueue(event);
assertEquals(1, persistentQueue.size());
}
}
But the queue size is 0 not 1. I dont know what's the problem. And I also have question about how to test the run method?
In your test method, you created a new queue that has nothing to do with your m_Processor instance; it goes unused entirely. You need to change your code so you can get the PersistentQueue instance contained inside your m_Processor instance. Assuming you have a getter method called getPersistentQueue inside Processor, then you can use the following:
#Test
public void test() {
m_Processor.addToQueue(event);
assertEquals(1, m_Processor.getPersistentQueue().size());
}
I am trying to write a Utility class that helps to execute a task on a Separate Thread, providing the ability to do something before the task starts, and something after the task ends.
Something similar to android's AsyncTask
Here is such a class.
class MySync
{
public void preExecute() {}
public void executeInBackground() {}
public void postExecute() {}
public final void execute()
{
threadExecute.start();
}
private final Thread threadExecute = new Thread()
{
#Override
public void run()
{
try
{
MySync.this.preExecute();
MySync.this.executeInBackground();
MySync.this.postExecute();
}
catch(Exception ex)
{
ex.printStackTrace();
}
}
};
}
Here is how this class is supposed to be used. Consumer of the class will override the methods as per the requirement.
class RegisterStudent extends MySync
{
#Override
public void preExecute()
{
System.out.println("Validating Student details. Please wait...");
try
{
Thread.sleep(2000);
}
catch(Exception ex)
{
ex.printStackTrace();
}
}
#Override
public void executeInBackground()
{
System.out.println("Storing student details into Database on Server. Please wait...");
try
{
Thread.sleep(4000);
}
catch(Exception ex)
{
ex.printStackTrace();
}
}
#Override
public void postExecute()
{
System.out.println("Student details saved Successfully.");
}
}
And finally starting the task:
public class AsyncDemo
{
public static void main(String... args)
{
new RegisterStudent().execute();
}
}
It seems to work fine. My question is, is this the correct way of achieving the Objective as mentioned in the Title? Any suggestions on how best this can be implemented?
What I don't like with your approach is the fact that you create a new thread each time you create a new instance of MySync which is not scalable if you intend to create a lot of instances of your Object moreover it is costly to create a Thread, if I were you I would use an executor in order to limit the total amount of threads allocated to execute your tasks asynchronously, here is how you can do it if you want to use only one thread:
ExecutorService executor = Executors.newFixedThreadPool(1);
I would also re-write your code for something like this:
public abstract class MySync implements Runnable {
#Override
public final void run() {
try {
preExecute();
executeInBackground();
} finally {
postExecute();
}
}
protected abstract void preExecute();
protected abstract void executeInBackground();
protected abstract void postExecute();
}
This way you define the whole logic for all the implementations.
Then you can submit your task like this:
executor.submit(new RegisterStudent());
What's bad about this is that you're forcing users to extend your class. In java you can only extend 1 class. So a framework should not take that away.
Rather use an interface:
public interface AsyncTask {
public default void preExecute() {}
public default void executeInBackground() {}
public default void postExecute() {}
}
And have users pass that to your utility class:
class MySync
{
private AsyncTask task;
public MySync(AsyncTask task) {
this.task = task;
}
public final void execute()
{
threadExecute.start();
}
private final Thread threadExecute = new Thread()
{
#Override
public void run()
{
try
{
MySync.this.task.preExecute();
MySync.this.task.executeInBackground();
MySync.this.task.postExecute();
}
catch(Exception ex)
{
ex.printStackTrace();
}
}
};
}
Loader is exactly what you are looking for.
Here is introduction for loader
https://developer.android.com/guide/components/loaders.html
https://developer.android.com/reference/android/content/Loader.html
I'm using a multiplayer Game Client that's called AppWarp (http://appwarp.shephertz.com), where you can add event listeners to be called back when event's happen, let's assume we'll be talking about the Connection Listener, where you need to implement this interface:
public interface ConnectionRequestListener {
void onConnectDone(ConnectEvent var1);
void onDisconnectDone(ConnectEvent var1);
void onInitUDPDone(byte var1);
}
My goal here is to mainly create a Reactive version of this client to be used in my Apps Internally instead of using the Client itself directly (I'll also rely on interfaces later instead of just depending on the WarpClient itself as in the example, but that's not the important point, please read my question at the very end).
So what I did is as follows:
1) I introduced a new event, named it RxConnectionEvent (Which mainly groups Connection-Related events) as follows:
public class RxConnectionEvent {
// This is the original connection event from the source client
private final ConnectEvent connectEvent;
// this is to identify if it was Connection / Disconnection
private final int eventType;
public RxConnectionEvent(ConnectEvent connectEvent, int eventType) {
this.connectEvent = connectEvent;
this.eventType = eventType;
}
public ConnectEvent getConnectEvent() {
return connectEvent;
}
public int getEventType() {
return eventType;
}
}
2) Created some event types as follows:
public class RxEventType {
// Connection Events
public final static int CONNECTION_CONNECTED = 20;
public final static int CONNECTION_DISCONNECTED = 30;
}
3) Created the following observable which emits my new RxConnectionEvent
import com.shephertz.app42.gaming.multiplayer.client.WarpClient;
import com.shephertz.app42.gaming.multiplayer.client.events.ConnectEvent;
import rx.Observable;
import rx.Subscriber;
import rx.functions.Action0;
import rx.subscriptions.Subscriptions;
public class ConnectionObservable extends BaseObservable<RxConnectionEvent> {
private ConnectionRequestListener connectionListener;
// This is going to be called from my ReactiveWarpClient (Factory) Later.
public static Observable<RxConnectionEvent> createConnectionListener(WarpClient warpClient) {
return Observable.create(new ConnectionObservable(warpClient));
}
private ConnectionObservable(WarpClient warpClient) {
super(warpClient);
}
#Override
public void call(final Subscriber<? super RxConnectionEvent> subscriber) {
subscriber.onStart();
connectionListener = new ConnectionRequestListener() {
#Override
public void onConnectDone(ConnectEvent connectEvent) {
super.onConnectDone(connectEvent);
callback(new RxConnectionEvent(connectEvent, RxEventType.CONNECTION_CONNECTED));
}
#Override
public void onDisconnectDone(ConnectEvent connectEvent) {
super.onDisconnectDone(connectEvent);
callback(new RxConnectionEvent(connectEvent, RxEventType.CONNECTION_DISCONNECTED));
}
// not interested in this method (for now)
#Override
public void onInitUDPDone(byte var1) { }
private void callback(RxConnectionEvent rxConnectionEvent)
{
if (!subscriber.isUnsubscribed()) {
subscriber.onNext(rxConnectionEvent);
} else {
warpClient.removeConnectionRequestListener(connectionListener);
}
}
};
warpClient.addConnectionRequestListener(connectionListener);
subscriber.add(Subscriptions.create(new Action0() {
#Override
public void call() {
onUnsubscribed(warpClient);
}
}));
}
#Override
protected void onUnsubscribed(WarpClient warpClient) {
warpClient.removeConnectionRequestListener(connectionListener);
}
}
4) and finally my BaseObservable looks like the following:
public abstract class BaseObservable<T> implements Observable.OnSubscribe<T> {
protected WarpClient warpClient;
protected BaseObservable (WarpClient warpClient)
{
this.warpClient = warpClient;
}
#Override
public abstract void call(Subscriber<? super T> subscriber);
protected abstract void onUnsubscribed(WarpClient warpClient);
}
My question is mainly: is my implementation above correct or should I instead create separate observable for each event, but if so, this client has more than 40-50 events do I have to create separate observable for each event?
I also use the code above as follows (used it in a simple "non-final" integration test):
public void testConnectDisconnect() {
connectionSubscription = reactiveWarpClient.createOnConnectObservable(client)
.subscribe(new Action1<RxConnectionEvent>() {
#Override
public void call(RxConnectionEvent rxEvent) {
assertEquals(WarpResponseResultCode.SUCCESS, rxEvent.getConnectEvent().getResult());
if (rxEvent.getEventType() == RxEventType.CONNECTION_CONNECTED) {
connectionStatus = connectionStatus | 0b0001;
client.disconnect();
} else {
connectionStatus = connectionStatus | 0b0010;
connectionSubscription.unsubscribe();
haltExecution = true;
}
}
}, new Action1<Throwable>() {
#Override
public void call(Throwable throwable) {
fail("Unexpected error: " + throwable.getMessage());
haltExecution = true;
}
});
client.connectWithUserName("test user");
waitForSomeTime();
assertEquals(0b0011, connectionStatus);
assertEquals(true, connectionSubscription.isUnsubscribed());
}
I suggest you avoid extending the BaseObservable directly since it's very error prone. Instead, try using the tools Rx itself gives you to create your observable.
The easiest solution is using a PublishSubject, which is both an Observable and a Subscriber. The listener simply needs to invoke the subject's onNext, and the subject will emit the event. Here's a simplified working example:
public class PublishSubjectWarpperDemo {
public interface ConnectionRequestListener {
void onConnectDone();
void onDisconnectDone();
void onInitUDPDone();
}
public static class RxConnectionEvent {
private int type;
public RxConnectionEvent(int type) {
this.type = type;
}
public int getType() {
return type;
}
public String toString() {
return "Event of Type " + type;
}
}
public static class SimpleCallbackWrapper {
private final PublishSubject<RxConnectionEvent> subject = PublishSubject.create();
public ConnectionRequestListener getListener() {
return new ConnectionRequestListener() {
#Override
public void onConnectDone() {
subject.onNext(new RxConnectionEvent(1));
}
#Override
public void onDisconnectDone() {
subject.onNext(new RxConnectionEvent(2));
}
#Override
public void onInitUDPDone() {
subject.onNext(new RxConnectionEvent(3));
}
};
}
public Observable<RxConnectionEvent> getObservable() {
return subject;
}
}
public static void main(String[] args) throws IOException {
SimpleCallbackWrapper myWrapper = new SimpleCallbackWrapper();
ConnectionRequestListener listner = myWrapper.getListener();// Get the listener and attach it to the game here.
myWrapper.getObservable().observeOn(Schedulers.newThread()).subscribe(event -> System.out.println(event));
listner.onConnectDone(); // Call the listener a few times, the observable should print the event
listner.onDisconnectDone();
listner.onInitUDPDone();
System.in.read(); // Wait for enter
}
}
A more complex solution would be to use one of the onSubscribe implementations to create an observable using Observable.create(). For example AsyncOnSubscibe. This solution has the benefit of handling backperssure properly, so your event subscriber doesn't become overwhelmed with events. But in your case, that sounds like an unlikely scenario, so the added complexity is probably not worth it.
I wrote a simple class that uses AbstractQueuedSynchronizer. I wrote a class that represents a "Gate", that can be passed if open, or is blocking if closed. Here is the code:
public class GateBlocking {
final class Sync extends AbstractQueuedSynchronizer {
public Sync() {
setState(0);
}
#Override
protected int tryAcquireShared(int ignored) {
return getState() == 1 ? 1 : -1;
}
public void reset(int newState) {
setState(newState);
}
};
private Sync sync = new Sync();
public void open() {
sync.reset(1);
}
public void close() {
sync.reset(0);
}
public void pass() throws InterruptedException {
sync.acquireShared(1);
}
};
Unfortunately, if a thread blocks on pass method because gate is closed and some other thread opens the gate in meantime, the blocked one doesn't get interrupted - It blocks infinitely.
Here is a test that shows it:
public class GateBlockingTest {
#Test
public void parallelPassClosedAndOpenGate() throws Exception{
final GateBlocking g = new GateBlocking();
Thread t = new Thread(new Runnable() {
#Override
public void run() {
try {
Thread.sleep(2000);
g.open();
} catch (InterruptedException e) {
}
}
});
t.start();
g.pass();
}
}
Please help, what should I change to make the gate passing thread acquire the lock successfully.
It looks like setState() only changes the state, but doesn't notify blocked threads about the change.
Therefore you should use acquire/release methods instead:
#Override
protected boolean tryReleaseShared(int ignored) {
setState(1);
return true;
}
...
public void open() {
sync.releaseShared(1);
}
So, overall workflow of AbstractQueuedSynchronizer looks like follows:
Clients call public acquire/release methods
These methods arrange all synchronization functionality and delegate actual locking policy to protected try*() methods
You define your locking policy in protected try*() methods using getState()/setState()/compareAndSetState()