I'm developing an android application that at high frequency receives data from ble notify, print data on the screen and send data to other peripherall.
This is my situation :
onCharacteristicChanged callback receives a byte array called
"value" at 10hz and unpacks data in some float and int variables
an Handler associated with an handlerThread starts a Runnable
every 30hz. This runnable use the variables unpacked from value,
saves the new data in some variables and sendbroadcastmessage to the
UX
another thread every 10hz use the data saved in
step 1 and 2 does some math operation on this variables and write
data on the characteristic.
In the step above I save and use float, double and int variables.
I'm afraid to handles the concurrency and I'm thinking to resolve the concurrency problems using the same handlerthread in the step 2 and 3. But when the other notify arrives I think that there is a race condiction problem :/
other question : oncharacteristicchanged in what thread is executed ?
more information of my problem :
in oncharacteristicchanged arrives new byte array (at 10hz frequency), I unpack data in variables , in other thread B (at 30hz) use this data do some calculation: sendbroadcast to the ux and save the result in some other variables; the thread C use the result of the thread B, it does some other calculation and write on characteristic at 10hz.
oncharacteristicchanged -> Thread B -> Thread C
But I can't stop oncharacteristicchanged because I don't know in what thread it is executed..
Do you
I don't understand Android, but I do Java. I'll try to help you even not knowing Android, so let's go!
"In the step above I save and use float, double and int variables."
First of all, I'd start using thread safe variables, such as: AtomicInteger or declare them as volatile.
For all your methods that will be accessed by multi-threading, I'd say to make them thread safe. I don't know if in Android there is the class Lock or the keyword synchronized, but I'd start from there.
Example:
Lock lock = new ReentrantLock();
try {
lock.lock();
doYourWork();
} finally{
lock.unlock();
}
Thats the way to start... Hope I helped you a little bit even not knowing Android and sorry if I said anything wrong.
Related
I have simple Activity that calls AsyncTask, so I print some id's regarding Proces and Thread:
From onCreate android.os.Process.myUid(): 10137
From onCreate android.os.Process.myPid(): 29776
From onCreate android.os.Process.myTid(): 29776
From onCreate Thread.currentThread().getId(): 1
/****************************************************************/
From Async doInBackground android.os.Process.myUid(): 10137
From Async doInBackground android.os.Process.myPid(): 29776
From Async doInBackground android.os.Process.myTid(): 30426
From Async doInBackground Thread.currentThread().getId(): 12556
Uid is same because its app-specific sandbox
Similar with Pid: Each app is one Process
3rd line in onCreate same as Pid because it's the UIThread and in Android OS as based on Linux we know that issue regarding Process is actually Thread etc... And in the Async the ThreadId is different because AsyncTask runs on different Thread rather then the UIThread
The thing I'm struggling to understand is Thread.currentThread().getId(). What I expect is to get same id as Thread.currentThread().getId() for the same execution environment. e.g. for onCreate I want lines 3,4 to be same (29776), and for Async I expect lines 3,4 to be the same (30426). What is going on here?
Thanks,
Very interesting question by the OP and I decided to dig (love open source).
The short answer is: they're different because they're different, because they were never meant to be the same.
Process.myTid() is the linux thread ID
Thread.getId() is a simple sequential long number.
But the short answer is boring, so let's explore where the answer comes from (links in the answer points to the relevant source codes).
In Process.myTid(), you'll see that is simply calls from Os.gettid() that in itself calls a native method on Libcore for that method is below:
public static int gettid() { return Libcore.os.gettid(); }
furthermore the docs for Os.gettid(); you'll find a link to Linux Programmer's Manual
gettid() returns the caller's thread ID (TID). In a single-threaded
process, the thread ID is equal to the process ID (PID, as returned
by getpid(2)). In a multithreaded process, all threads have the same
PID, but each one has a unique TID.
That means, Process.myTid() returns the thread ID as given by the Linux kernel.
On the other hand Thread.getId() is simply returning a long. This long is assigned during init(...) as tid = nextThreadId();. Then the last piece of this puzzle, below is the code for nextThreadId()
/* For generating thread ID */
private static long threadSeqNumber;
private static synchronized long More ...nextThreadID() {
return ++threadSeqNumber;
}
That means, Thread.getId() is simply a "java layer" static long being auto-increment for each thread.
Hello I am having issues in regards to running threads in Android with Python SL4A. I am trying to run two threads at the same time, but seem to be having issues
from threading import *
import time
def func1():
while True:
print("func1")
def func2():
while True:
print("func2")
thread = Thread(target = func1)
thread.start()
for i in range(1000):
thread = Thread(target = func2)
thread.start()
time.sleep(2)
time.sleep(2)
the first thread func1 starts fine but then is never run again once func2 takes over.
Would anyone have any advice on how to fix this?
Thank you
I'm not sure what you're expecting here. You first pass func1 into a thread, then start it. You never reference func1 or the thread again after that.
Later, you create an iterator, within which you pass func2 into a new thread and start it. You repeat that process a thousand times, with a two second sleep between each.
Do you want both functions to run a thousand times? If so...
thread1 = Thread(target=func1)
thread2 = Thread(target=func2)
for i in range(1000):
thread1.start()
thread2.start()
time.sleep(2)
Note that in your code the variable thread is assigned Thread(target=func1) before the iterator. Inside the iterator, the same name, thread, is assigned Thread(target=func2), so it no longer points to the same thing.
Also, if you're creating an object to reference it in a loop, you want to try and keep the initialisation outside of the loop, so you don't create the same object over and over. Just create one, then reference it in the loop.
I recall reading somewhere that android guarantees that LruCache provides latest info for all threads, and that one thread's operation will complete before the same thread sees an edit on the cache from another thread. I am using LruCache to store bitmaps obtained from my app's server, and using a pool of threads to obtain bitmaps from the network.
Now I cannot find the reference to this in the Android docs or any other mention. Do I need to mark LruCache instances as volatile or set synchronize(LruCache) around cache operations?
mibollma is not wrong in his response regarding Android LruCache Thread Safety. People often mistake thread safety and atomicity.
If a class is thread safe, it means that, when for instance two threads call an operation on it, the internals do not break. Vector is such a class with every operation being synchronized. If two different threads call Vector.add, they will both synchronize on the instance and the state is not broken. For instance something like this:
synchronized void add(final T obj) {
objects[index++] = obj;
}
This thread-safe in the sense that no two threads will add an element at the same position. If it would not be synchronized they could both read index = 0 and try to write at that position.
Now why do you still need to synchronize? Imagine you have a case like this:
if(!collection.contains(element)) {
collection.add(element);
}
In that case your operation is not atomic. You synchronize once, when you ask if the element is already present and a second time when you add that element. But there is a window in between those two calls when another thread could make progress and your assumption of the collection not containing the element is broken.
In pseudo code:
if(!coll.contains(element)) { // << you have the exclusive lock here
//Thread 2 calls coll.add(element) << you do not have the lock anymore
coll.add(element); // << doomed!
}
So this is why the answer is correct in the sense that you should synchronize around non-atomic operations like
synchronized(coll) {
if(!coll.contains(element)) { // << you have the exclusive lock here
// Thread 2 wants to call << still holding the lock
// coll.add(element) but
// cannot because you hold the lock
coll.add(element); // << unicorns!
}
}
Because synchronization is pretty expensive the concurrent collections come with atomic operations like putIfAbsent.
Now back to your original question: should you make the LruCache volatile? In general you do not mark the LruCache itself volatile but the reference to it. If such a reference is shared across threads and you plan to update that field then yes.
If a field is not marked volatile a thread might not see the updated value. But again: this is just the reference to the LruCache itself and has nothing to do directly with its contents.
In your specific scenario I would rather have the reference final instead of volatile since no thread should set the reference to null anyways.
The question if you need to put synchronized around your cache operations depends on the case. If you want to create a single atomic operation, like putIfAbsent, then yes.
public void putIfAbsent(final K key, final V value) {
synchronized(lruCache) {
if(!lruCache.containsKey(key)) {
lruCache.put(key, value);
}
}
}
But later in your code, when you call just lruCache.get(key) there is no need to wrap that into a synchronized block itself. Only when you plan to create an atomic operation that should not interfere with another thread.
In my problem, I create a pthread using pthread_create(), say myThread.
They both share a common variable "done" for the main thread to tell the myThread stops reading from the socket.
in my pthread, I have a loop:
// done is a common variable
while (!done && socket->read(&buffer) == OK) {
// do something....
}
Some times, I want to tell myThread to stop reading from socket, so I do:
done = true;
void *test;
pthread_join(myThread, &test);
Will this cause a race condition? i.e. will myThread not see my main thread update the value of 'done' before it blocks on the read call?
Writing a variable in one thread and reading it in another needs synchronization (such as a mutex) to avoid race conditions.
If this is a real socket and not a strange object, consider calling shutdown() to tear down the connection and wake up blocked threads while keeping the file descriptor valid, see Wake up thread blocked on accept() call. Once the read has failed, myThread locks the mutex and checks the done variable.
Other methods include calling poll() on the socket and a pipe for delivering the shutdown message.
My program is sending data to web server when accelerometer datas exceed the threshold which determined by me. So , I used thread mechanism for sending operation :
if( threshold is exceeded )
thread_send .start();
But this usage cause "Thread Already Used" error. So I used a method that I think is bad is below and it works :
if( threshold is exceeded ) {
thread_send = new Thread(this);
send_thread.start();
}
New thread is created at every turn. Does that usage cause negative results? (For example, memory problem or performance problem etc.)
What are your suggestions?
Editted :
My program should send data to web server very often. The most important thing is working correctly.So slow working is allowable , as long as the program can't stop suddenly..
I used ExecutorService in line with your suggestions :
ExecutorService threadExecutor = Executors.newSingleThreadExecutor();
........
if( threshold is exceeded ) {
threadExecutor.execute(this);
}
But errors occured : RecejtedExecutionException..
What can I do ?
The second code looks correct, though it may slow it down if too many threads are running in parallel. Depending on the application, it might be appropriate to have threads run one-at-a-time in a queue, using Executors.newSingleThreadExecutor.
One idea is creating a singleton like service that runs the thread, that way if one isn't running, then it starts one, otherwise it ignores it.
If you want multiple running at the same time, what you have is correct. Remember a thread can only be ran once per new Thread()