I have written some database queries in synchronized method. Ideally if some code is executing inside this code block then other thread should not access this but it does sometimes in my case.
synchronized private void func1 () {
// printing some log for start
// some database code
// printing log at the end
}
So the log which i have printed at the start prints twice. How to block this thing?
The synchronized block uses a lock on the object that calls func1(). If you call func1 from different threads using different objects the situation encountered is possible.
Assuming you have
class A {
synchronized private void func1() {}
void func2() { func1()}
}
And call from 2 different threads new A().func2(), func1() is not thread safe in this case.
If you have only 1 instance of class A in my example than it must work.
Related
public static void main(String[] args) {
new Thread(new Runnable() {
#Override
public void run() {
getLinks();
}
});
}
}
private void getLinks(){
String link;
// my work
Download(link);
}
private void Download(String Link){
// my work
}
Will the other method also run in that thread, as we called getlinks() then getlinks() called the Download() method, will the downloading will run in the background or I have to stay my activity open, in my android app.
Fact: When we are using IntelliJ IDE and we all know that there is a method named as public static void main(String ars[]){ } remember? So this is a method and all the code that runs in this method will run in the main thread.
Answer - So if we call a method from a thread then each line of code in that method, will run in that thread.
Example : So the thread is a car and anything that is called by this car will travel in that car , even if a person is called by a person who is already traveling in that car will have to travel in that car. Each person need a car to travel. Each method needs a thread to run.
Extra Fact - You know in android, there is a thread called UI thread, so whenever you want to make changes to UI then u have to use that thread or it will crash the app.
I recommend you this udemy course [ by Michael Pogrebinsky ] to understand multithreading in java. Java Multithreading, Concurrency & Performance Optimization
I've a Worker in which i first want to apply FFMPEG command before uploading it to server. As Worker is already running in background so to keep the result on hold until file uploads I've used RxJava .blockingGet() method. But I'm unable to understand that how to execute FFmpeg command synchronously by anyway i.e. RxJava etc. One tip that I found is to use ListenableWorker but it's documentation says that it stops working after 10 minutes. So, i don't want to go with that solution. Following is the method of FFmpeg just like any other async method. How can i make it synchronous or integrate it with RxJava? Any ideas would be appreciable.
ffmpeg.execute(command, new ExecuteBinaryResponseHandler() {
#Override
public void onFailure(String s) {
}
#Override
public void onSuccess(String s) {
uploadMediaItem(mediaUpload);
}
#Override
public void onProgress(String s) {
}
#Override
public void onStart() {
}
#Override
public void onFinish() {
// countDownLatch.countDown();
}
});
This is the flow of my Worker:
check pending post count in DB.
Pick first post and check if it has pending media list to upload.
Pick media recursively and check if editing is required on it or not.
Apply FFmpeg editing and upload and delete from DB.
Repeat the cycle until last entry in the DB.
Thanks
If you wanna create a syncronous job you need to use the CountDownLatch class (there is a comment in your code).
CountDownLatch is a syncronization object that can be used in cases like this.
As for now there isn't a valid method to have sync workers.
Listenable workers is useful when you want to monitor the worker itself from your app using a Livedata that return useful information (e.g. the status).
If I remember correctly the standard Worker class also descend from Listenable worker so you can use that.
In your case is useful to have two workers: the first apply a FFMPEG command, and the second worker that take the output of this command to do the network upload. Separating this two operations allows you to have more time for complete the two works (10 + 10).
In your case you can do something like this for the first worker:
private final CountDownLatch syncLatch = new CountDownLatch(1);
...ctor
doWork(){
//your asyncronous call
...
#Override
public void onFinish() {
//you need to save error status into a onSuccess and onFailure
syncLatch.countDown();
}
...
//end
syncLatch.await();
...
//evaluate if there are errors
...
//create output to pass to the next worker
Data outputData = ...
//pass the result to second worker, remember that onfailure will stop all subsequent workers
if(error==true)
{
return Result.failure(outputData);
}else{
return Result.success(outputData);
}
}
For the second worker you can do the same according to your upload function behavihour to syncronize the call.
Hope this help.
Cheers.
I need to use threads in my android application because I am doing image processing w/ native opencv. Here is my code:
void Detector::processBinary(Mat &binary) {
//do stuff
}
void Detector::Detect() {
...
thread t1(processBinary, binary);
t1.join();
}
However, I get the error "invalid use of non-static member function" from thread t1(processBinary, binary) whenever I try to run the app. This line, however, works perfectly in visual studio. Can anyone help me with this? Thanks in advance!
You use member function, that needs this argument (it must be called on some object). There are two alternatives:
Use static class function (or non-class function at all):
void processBinary(Mat &binary) {
//do stuff
}
void Detector::Detect() {
...
thread t1(processBinary, binary);
t1.join();
}
Or pass proper arguments if we want utilize member function:
void Detector::processBinary(Mat &binary) {
//do stuff
}
void Detector::Detect() {
...
thread t1(&Detector::processBinary, *this, binary);
t1.join();
}
Example:
Sync Vesrion:
int weather = getWeather();
Async version:
getweather(callback) to the other class and when other class ready to return value it use callback. callback.receiveWeather(temperature); and callback object has a overridden receiveWeather(int) method.
Question:
now how do i convert async method to sync call in android. can you give me a example ? i know it has something to do thread , wait() etc .. but do not know to implement it.
The following code does what you want, but it is far more preferable to just create a blocking getter and wrap it with AsyncTask in case async routine is also needed.
When this is nested, be sure not to
wait() the main thread
run both segments in the same thread
Especially if you wrap some async only API with not well documented threading mechanism, this can make both method running on the same thread.
public class AsyncToSync{
private Object lock= new Object();
private boolean ready = false;
public syncCallToAsyncMethod(){
new AsyncMethodProvider().doAsync(new CompletionListener(){
public void onComplete(){
// TODO: Do some post-processing here
synchronized(lock){
ready = true;
lock.notifyAll();
}
}
})
synchronized (lock) {
while (!ready) {
try {
lock.wait();
} catch (InterruptedException e1) {
e1.printStackTrace();
}
}
}
}
}
See Guarded Blocks.
In the called method, instead of calling the callback method and passing in the result, just return the result. So change the method signature from this:
public void getWeather(WhateverCallback<Type> callback)
To this:
public Type getWeather()
I'm trying to create a simple multiplayer game. There's a WorkerService which is supposed to handle all network communication and all interaction between this service and my Activities is done with AIDL. I think this is a standard approach - to enable two way interaction I use also an IWorkerCallback interface (also AIDL).
The problem is that callbacks have to change things in UI which may be done only in UI thread. I've created a Handler (in UI thread) and believed that this is an obvious solution. But, surprisingly, it's not working.
My LoungeActivity calls startServer() method of IWorker interface. Corresponding method of my WorkerService does some job and makes a callback - this works fine. Then WorkerService spawns a new thread and callback from this thread results in a bad Exception being thrown:
Can't create handler inside thread that has not called Looper.prepare()
Here's some code to make it clear:
startServer() implementation:
private void startServerImpl(String name, float latStart, float latEnd,
float lonStart, float lonEnd)
{
// some instructions here
// this works fine:
callback.notifySocketCreated();
// my naughty thread:
new ServerThread().start();
// some instructions here
}
ServerThread code:
private class ServerThread extends Thread {
#Override
public void run()
{
//some instructions here
// this call will cause an error
callback.notifyGameRegistered();
}
}
Every method from callback looks like that:
public void notifyGameRegistered() throws RemoteException
{
handler.dispatchMessage(handler.obtainMessage(CALLBACK_GAME_REGISTERED));
}
In Handler's handleMessage() method I'm doing a simple switch(msg.what) and in every case there's a simple UI modification (showing a Toast, changing Text, etc.).
I have no idea why is this Exception thrown.. I've managed to fix it by packing code into a Runnable and calling runOnUiThread() but it still makes me curious - shouldn't a Handler always run in thread that created it? Or maybe I'm doing something wrong?
I know this is a bit late - but the problem is that you called dispatchMessage().
The correct method is sendMessage().
dispatchMessage() will call handleMessage() on the same thread.
I am guessing the problem is not your Handler being on the wrong thread - but that the UI is trying to create a Handler somewhere in yout onHandle() method. Because onHandle() is called on the wrong thread, you are getting an exception.
/**
* Handle system messages here.
*/
public void dispatchMessage(Message msg)
{
if (msg.callback != null) {
handleCallback(msg);
} else {
handleMessage(msg);
}
}
You have to somehow call the offending function from the main thread.
The function that changes the UI should be in the activity that owns the UI.
This link should help you out:
http://android-developers.blogspot.com/2009/05/painless-threading.html