I have an app that needs to use a connection to a server over multiple sockets in different activities. I have set up a service which handles the connection throughout the program and holds all the input and output streams. The problem I am having is that i want to access the input streams from different activities using threads and im not sure how to do this without calling the streams each time from the service class in each activity which causes interference problems because multiple threads are retrieving the same data.
Does anyone have any ideas on how i should i should proceed, any help will be greatly appreciated.
well, if i got it correctly; your input stream object seems to be critical section. so you need a mechanism like semaphore that controls the usage of that stream object. otherwise, you can't know if there is an interference. Maybe i'm just wrong but it may lead you to a solution.
Related
I know this subject has been discussed here before, and we have utilized past conversations to attempt to resolve the DbMaxReadersExceededException that we are still experiencing. We are using version 2.5.1 of ObjectBox. We are also, heavily, using RxJava threads while manipulating our BoxStore DB. At any moment in time, potentially a handful of RxJava threads are running, accessing the DB. Threads are constantly spawning, executing and terminating.
This is a very "non-standard" use of Android. Our App is running on a non-cell phone device, that sits on a wall and is expected to be available 24x7. 95% of the RxJava threads that access the BoxStore DB are short lived, get in / get out threads, that retrieve information and present to the device user. We do have a few longer lived background RxJava threads, that talk to an external DB over the internet to keep the local DB up to date. But these threads to spawn, execute and terminate. Theses threads run in the background at regular intervals. These background threads are not associated with a Fragment nor Activity; therefore the common way of cleaning up, using a CompositeDisposable, is not utilized.
We are seeing that readers are accumulating, despite many attempts to resolve the situation. We have also noticed that threads, that have run to termination, marked as isAlive and appear to be part of the RxJava thread pool, also accumulate. We have observed this using Thread.getAllStackTraces() and printing out this information regularly. Separate issue I am not trying to resolve with this post (I am concentrating on the DbMaxReadersExceededException issue, but they may be related).
The readers accumulate as the result of .find() calls on a Query that is build; based upon analysis of when a reader occurs. That is not surprising, but sometimes a .find() causes a new reader and sometimes it does not. I do not understand this behavior, and I am not sure if that is a telling sign or not. But it does result in the accumlation of active readers everytime the RxJava thread that accessed a given Box is invoked.
Any help / assistance offered will be greatly appreciated. Please ask any questions about anything that I may have accidental left out.
Things that we have tried, based upon other posts that I have read, include:
Collect Disposables from RxJava background threads and dispose
We have tried collecting the Disposable generated by the .subscribe() from these background threads, and added a timer to .dispose() of them sometime (5 seconds) after the thread that was using this object terminates (run to completion).
Utilized BoxStore.diagnose()
We have written code to utilize BoxStore.diagnose() to be able to periodically watch the reader accumulation.
Tried BoxStore.closeThreadResources()
We have added BoxStore.closeThreadResources() calls when an RxJava thread terminates to cleanup any BoxStore resources that may be active.
Tried Box.closeThreadResources()
We have tried adding Box.closeThreadResources() calls closer to when the Box is accessed in order to access and then clean up ASAP.
Tried breaking down .method() sequence and added .close() calls to itermediate objects
We have tried breaking down the .method() call sequence that terminates with the .find() call and then .close() or .closeThreadResources() the intermediate objects along the way.
Tried combinations of the above
We have tried a combination of all of the above.
Wrote method to be able to monitor RxJava threads using Thread.getAllStackTraces() - RxJava threads seem to accumulate
We have written a method that helps us monitor RxJava threads using Thread.getAllStackTraces().
We have tried to manually invoke the Garbage Collector
We added code, after the .dispose(), mentioned above, to cause a manual Garbage Collection (System.gc()).
As far as I know, we have tried every suggestion that I have seen posted on this and other forms, regarding this issue. We are at a loss as to what to do or try next. I did see something about a package called RxObjectBox, but I have not pursued this any further.
Should we:
Look at restructuring our RxJava thread access?
Do we need to look closer at RxObjectBox?
Is there a known problem with ObjectBox 2.5.1 that we should be using a later version?
What haven't we tried that we should?
I have a problem caused by multi-threading and Android Open Accessory.
I need to communicate with a USB Accessory, but I need to do it from 2 threads. One thread generates and sends data the other one reads data.
Why I don't use a single thread? Because there can be 1 or more writes before a read and reads are blocking, so that is not an option.
If using multiple threads, I do run into "I/O Error (No such device)" sooner or later, because I will have a collision between read & write being executed at the same time.
Locking will more or less put me back in single-thread situation, so not good.
.available() method on the input-stream returns is not supported, so I cannot check if anything is available before doing a read
Since it's not a socket-based stream I cannot set timeout either.
I have tried getting the FileDescriptor from the USBAccessory and passing to JNI to handle it there, but after the first read/write the device becomes inaccessible.
Question/Suggestion needed:
What will be a suggested/best-practice approach to this? I do not expect written code, I just need some guidance on how to approach this problem.
To clarify:
The software at the other end might or might NOT respond with any data. There are some so called silent sends were the data sent it's just received but there is no ACK. Since the app I'm working on is only a proxy, I do not have a clear picture if the data will or will not produce an answer. That will require analysis of the data as well, which isn't on the books at the moment.
As you want to do read and write in parallel, writing will always lead to a pause to read if the read is on the same part as write.
May be you can follow similar approach as ConcurrentHashMap and use different locks for different segments and lock read only if write is on the same segment else allow the read to happen.
This will
Avoid blocking read during write in most scenarios
Avoid collision and
Definitely wont be a single thread approach.
Hope that helps.
If using multiple threads, I do run into I/O Error (No such device)
sooner or later, because I will have a collision between read & write
being executed at the same time.
This says it all. Since you are doing read and write on the same channel that does not support concurrent access, you are required to have your thread wait until the other thread is done doing read/write.
Your two-thread approach is what I would do, more or less. Good luck and trust in yourself.
I have a Java project where I am required to both send and receive network packets with only the Ethernet header present. The header contains custom MAC addresses as well, which do not match the physical hardware address of the receiving/sending interface.
I have selected jNetPcap 1.3 to accomplish this task, but I am concerned about the thread safety of my Java application and am in need of some help with the particularities of libpcap.
I have two threads, where the first thread executes a
org.jnetpcap.Pcap.loop(Pcap.LOOP_INFINITE, handler, outputQueue)
loop to capture packets from a previously opened org.jnetpcap.Pcap Object (representing a pcap_t) passed to the thread by the caller.
The second thread is supposed to pick payload/header pairs from an input queue and send them using
org.jnetpcap.Pcap.sendPacket(packetByteBuffer)
using the SAME org.jnetpcap.Pcap Object as the thread executing the reception loop.
Problem:
From using google I concluded that this approach is not working because libpcap is not threadsafe when accessing the same pcap_t object from different threads.
Theoretical Solution:
I think the solution to my problem is to create two separate instances of org.jnetpcap.Pcap, open them separately using org.jnetpcap.Pcap.openLive() and passing one instance to the transmission thread and one to the reception thread.
Before I run off changing a lot of code, I hope someone can confirm that this is indeed the right approach to solving this problem.
Thanks in advance for your answers.
You must in some way synchronize access between the threads, e.g. you could use
Pcap.breakloop() and break the loop that receives packages to send some and continue the loop afterwards.
Pcap.dispatch() and a short timeout for Pcap.openLive() and switch between queued packages to be send and receiving packages.
From the jNetPcap Documentation: It is however safe to interact with various Pcap objects from multiple threads, as long as access is externally synchronized.
I'm writing a simple application for an android phone to communicate with a PC over a socket connection.
The phone might write or recieve a message at any time, and the computer might as well.
The solution I have used so far works like this:
Create a thread and call READ in it.
Run an infinte loop.
Check if thread has finished,
If so grab the READ and process,
Then start a new thread also calling read.
Check to see if another object working in another thread wants to write,
If so grab and write.
Specifically, I am using AsyncTask from the Android API to run the threads.
It all works fine, but I am wondering if creating a new thread for each READ is too performance heavy and/or bad coding, and if so how I can reuse the same thread to have the same behaviour.
Alternatively, is there a better way to handle this situation overall?
Thanks in advance for any advice!
Yes, creating a new thread for each read is grossly inefficient for your described need.
Instead, consider creating a single thread, a List<your data type> to hold reads, and a semaphore to flag that data is available. Your thread reads each message, places it into the list, and posts the semaphore to whatever is waiting for data. That 'whatever' then receives whatever is in the list until it empties it, then goes back to waiting on the semaphore.
You need one read thread and one write thread. Both should use a BlockingQueue to interface with the rest of the application. Although I don't understand why you would have multiple threads wanting to write.
My application is currently using ordinary threads to produce servers, clients and even a thread which swaps WiFi networks and starts the previous. Those threads run in the background and dont have any impact on the UI so it is something I was looking for, but the problem is that when I reenter the application all those threads are recreated. Is it possible to create a singleton thread which will be possible to control when we reopen the application?
Android offers some classes also:
Service: but it uses the UI thread...
AsyncTask: probably a better candidate
IntentService: has a worker thread which could be manipulated? Probably best option from above.
Any thoughts/opinions will be highly appreciated. :)
EDIT:
Also why I would want to change my ordinary threads into some other method is because Android will prioritize ordinary threads to get killed.
Thread call hierarchy:
MainActivity -> NetworkSwap(infinite process which is scanning, connecting and swaping WiFi networks), ServerTCP(infinitely listening for connections) , ServerUDP(infininetely listening for connections)
Networkswap -> ClientUDP (sends broadcast request to serverUDP and ends)
ServerUDP -> ClientTCP (sends request to serverTCP and ends)
It's still not entirely clear to me what you're using these threads for. From the title it seems you're doing ongoing work, but in the description it sounds like sometimes you do smaller discrete chunks of work. It's also not clear whether these types of work are related.
That said, with ongoing work I'd say to move your currently existing thread to be managed by a regular Service, thus giving a lifetime that is independent of activities and can do ongoing background work. For smaller discrete chunks of work, IntentService is a better match. If you have these two types of work and they're not very related, you could even consider having both types of services (it sounds like you have multiple threads as is anyway).