I am new to android programming.Sorry if this type of question have been asked before.
I am getting trouble while creating threads.In my code, I have initialized int i=500; and in my first thread t1, i want to increment the value of t1 if(i<5000) and also on my thread t2 want to check the condition where the value of t2 is decremented if(i>0)
Please help...Thanks in advance
Here is the plain java Thread implementation for android as you required for this specific increment/decrement problem...
// class lass level declarations
private static int DEF_VALUE = 500;
private static int MIN_VALUE = 0;
private static int MAX_VALUE = 1000;
private AtomicInteger i = new AtomicInteger(DEF_VALUE);
private Thread t1 = null;
private Thread t2 = null;
private void initThreads() {
Log.i(TAG, "Initializing Threads...");
t1 = new Thread(new Runnable() {
#Override
public void run() {
Log.i(TAG, "Starting T1.");
while (i.get() < MAX_VALUE) {
i.incrementAndGet();
Log.d(TAG, String.format("Incremented by T1, i = %d", i.get()));
}
Log.i(TAG, "Finishing T1.");
}
});
t2 = new Thread(new Runnable() {
#Override
public void run() {
Log.i(TAG, "Starting T1.");
while (i.get() > MIN_VALUE) {
i.decrementAndGet();
Log.d(TAG, String.format("Decremented by T2, i = %d", i.get()));
}
Log.i(TAG, "Finishing T2.");
}
});
t1.start();
t2.start();
}
Hope this helps...:)
Update: Source updated to use AtomicInteger instead of plain int to avoid concurrent access issues.
You can do this by using AsyncTask: http://developer.android.com/reference/android/os/AsyncTask.html
Do note that in some versions on Android, AsyncTask is executed on a single thread. If you need to execute in paralell this need to be set on the task, from the documentation:
When first introduced, AsyncTasks were executed serially on a single background thread. Starting with DONUT, this was changed to a pool of threads allowing multiple tasks to operate in parallel. Starting with HONEYCOMB, tasks are executed on a single thread to avoid common application errors caused by parallel execution.
If you truly want parallel execution, you can invoke executeOnExecutor(java.util.concurrent.Executor, Object[]) with THREAD_POOL_EXECUTOR.
In addition, you will run into concurrency issues, so you should take steps to handle them.
It might look like this:
public class DoingTwoThings {
private AsyncTask<Void, Void, Void> taskA;
private AsyncTask<Void, Void, Void> taskB;
private volatile int i;
public DoingTwoThings() {
createTaskA();
createTaskB();
startTasks();
}
private void createTaskA() {
taskA = new AsyncTask<Void, Void, Void>() {
#Override
protected Void doInBackground(Void... voids) {
doInBackgroundA();
return null;
}
};
}
private void doInBackgroundA() {
while (i < 5000) {
i++;
}
}
private void createTaskB() {
taskB = new AsyncTask<Void, Void, Void>() {
#Override
protected Void doInBackground(Void... voids) {
doInBackGroundB();
return null;
}
};
}
private void doInBackGroundB() {
while (i > 0) {
i--;
}
}
private void startTasks() {
// AsyncTasks executed one one thread in Honeycomb+ unless executed in thread pool manually
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
taskA.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
taskB.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
} else {
taskA.execute();
taskB.execute();
}
}}
The code in the overriden "doInBackground()" methods are executed on a different thread. If you need to modify some UI before or after the task is done you can easily override onPreExecute and onPostExecute.
Related
I don't know if there are any other good ways to achieve the results I want, thank you.
I have a requirement, according to the URL, create multiple webview threads, and execute them in order, such as thread execution, then trigger thread two execution, and so on, I use the synchronized (lobject) method, but in JAVAfx encountered a problem, the code is as follows:
public class LockObject {
public int orderNum = 1;
public final static int MaxValue=9;
public LockObject(int orderNum){
this.orderNum = orderNum;
}
}
public class DownloadThread extends Thread{
private LockObject lobject;
private int printNum =0;
private String url;
public DownloadThread(LockObject lobject,int printNum,String url){
this.lobject=lobject;
this.printNum = printNum;
this.url = url;
}
#Override
public void run() {
synchronized(lobject){
while(lobject.orderNum <= lobject.MaxValue){
if(lobject.orderNum == printNum){
System.out.print(printNum);
Platform.runLater(new Runnable() {
#Override
public void run() {
webView.getEngine().load(url);
webView.getEngine().getLoadWorker().stateProperty().addListener(new ChangeListener<Worker.State>() {
#Override
public void changed(ObservableValue<? extends Worker.State> observable, Worker.State oldValue, Worker.State newValue) {
if (newValue == Worker.State.SUCCEEDED) {
try {
//xxxxx
// java.lang.IllegalMonitorStateException
lobject.notifyAll();
} catch (Exception e) {
e.printStackTrace();
}
}
}
});
}
});
lobject.orderNum++;
if(lobject.orderNum==downloadThreads.length){
saveCsvFile(goodCSVS);
}
//lobject.notifyAll(); is ok
}else{
try {
lobject.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
}
Place of call
private DownloadThread[] downloadThreads;
LockObject lobject = new LockObject(1);
downloadThreads = new DownloadThread[tableView.getItems().size()];
for (int i = 0; i < tableView.getItems().size(); i++) {
UrlModel item = tableView.getItems().get(i);
downloadThreads[i] = new DownloadThread(lobject,tableView.getItems().size()-i,item.getLink());
downloadThreads[i].start();
}
Calling lobject.notifyAll() in the run method in Platform.runLater will report an IllegalMonitorStateException. After the address is processed, I want to wake up the next thread to execute.
If you need to execute multiple tasks in order, there's no need to create multiple threads. Just using a single thread will guarantee the next task only executes after the previous one has completed. You should also consider using a CountDownLatch instead of synchronizing on an object.
ExecutorService executor = Executors.newSingleThreadExecutor();
try {
for (UrlModel model : tableView.getItems()) {
executor.submit(() -> {
CountDownLatch latch = new CountDownLatch(1);
Platform.runLater(() -> {
engine.load(model.getLink())
engine.getLoadWorker().runningProperty().addListener((obs, ov, nv) -> {
if (!nv) {
latch.countDown();
}
});
});
latch.await();
// do whatever needs to happen after the WebEngine finishes loading
return null; // using #submit(Callable) and Callable needs to return something
});
}
} finally {
executor.shutdown();
}
Some notes:
You may want to avoid creating the ExecutorService if the table has no items to process. That is, assuming you don't reuse the same ExecutorService every time.
If you reuse the ExecutorService, don't call shutdown().
This ExecutorService uses non-daemon threads. You can customize this by supplying a ThreadFactory that creates daemon threads.
I added a listener to the Worker#running property instead of the status property to make it easier to ensure countDown() is invoked no matter the terminal status of the load (i.e. whether it's SUCCEEDED, CANCELLED or FAILED).
You may want to remove the the listener added to the Worker's property when it's finished. You can do this by using an anonymous class (rather than the lambda expression I used) and calling obs.removeListener(this) inside the changed method, where obs is the ObservableValue argument.
So I had a crack at coding my own AsyncTask class like system that runs on a ThreadPoolExecutor natively. Everything was working fine until I decided to implement the progress side of things. The progress works much like AsyncTask, the onProgressUpdate function is called on the UI thread. The problem I'm experiencing is that whenever there is a System.out or Log.x line in the onProgressUpdate it hangs indefinitely with no error or warning oddly. The code is as below:
public abstract class Task<A, B> {
private static final Executor EXECUTOR = getExecutor();
private static final int DEFAULT_PRIORITY = Thread.MIN_PRIORITY;
private static final int DEFAULT_PROGRESS_INCREMENT = 1;
private static final Executor getExecutor() {
ThreadPoolExecutor executor = (ThreadPoolExecutor) Executors.newCachedThreadPool();
executor.setCorePoolSize(1);
executor.allowCoreThreadTimeOut(false);
// TODO set rejection handler
//executor.setRejectedExecutionHandler(new Handler());
// TODO set thread factory
executor.prestartCoreThread();
return executor;
}
public static class ExecutionListener<B> {
public void onPreExecute() {
Log.i("TASK", "Pre - Thread: " + Thread.currentThread().getId());
}
public void onPostExecute(B output) {
Log.i("TASK", "Post - Thread: " + Thread.currentThread().getId() + " - Output: " + output);
}
public void onProgressUpdate(int progress) {
Log.d("TASK", "Hello");
}
}
private Handler handler;
private ExecutionListener<B> executionListener;
private volatile int progress = 0;
private AtomicBoolean progressPublished = new AtomicBoolean(true);
private B output;
public Task() {
this.handler = new Handler();
this.executionListener = new ExecutionListener();
}
public void setExecutionListener(ExecutionListener executionListener) {
if(executionListener == null) {
this.executionListener = new ExecutionListener();
}
else {
this.executionListener = executionListener;
}
}
protected void updateProgress(int progressMade) {
Log.d("TASK", "Test");
progress += progressMade;
if(progressPublished.compareAndSet(true, false)) {
if(!handler.post(new Runnable() {
#Override
public void run() {
Log.d("TASK", new Integer(progress).toString() + " - a");
executionListener.onProgressUpdate(progress);
// Hangs below
progressPublished.lazySet(true);
Log.d("TASK", new Integer(progress).toString() + " - b");
}
})) {
Log.d("TASK", "Failed to post");
}
}
}
protected void updateProgress() {
updateProgress(DEFAULT_PROGRESS_INCREMENT);
}
protected abstract B doTask(A input);
public void execute(final A input, final int priority) {
EXECUTOR.execute(new Runnable() {
#Override
public void run() {
Thread.currentThread().setPriority(priority);
handler.post(new Runnable() {
#Override
public void run() {
executionListener.onPreExecute();
}
});
output = doTask(input);
if(!handler.post(new Runnable() {
#Override
public void run() {
Log.d("TASK", "Done");
executionListener.onPostExecute(output);
}
})) {
Log.d("TASK", "Failed to post post");
}
}
});
}
public void execute(final A input) {
execute(input, DEFAULT_PRIORITY);
}
}
The ExecutionListener is just a class to override the methods to be run on the UI much like AsyncTask's methods for doing the same. The code uses Runnable objects to execute the doTask method and send updates / the result to the appropriate method in the ExecutionListener.
The Thread.currentThread() parts are just to ensure things are running on the thread I intended them to. The problem only shows itself when running a Task that frequently calls updateProgress() - I have tried putting a thread sleep in the onProgressUpdate() method and that seems so solve things, though that obviously isn't a good solution.
It also only seems to have a problem with Log.x / System.out - I don't know whether the call frequency of either of them could cause this kind of issue. I'm at a loss with this progress feature and logging so any advice would be greatly appreciated - I've also found this quite hard to explain so please ask if you need me to clarify anything!
Turns out the Thread.currentThread().getId() is at fault. Removing that part fixes everything. Follow up question here: Is Java Thread getId() thread-safe?
I am parallelizing my operation by splitting it in the exact number of cores available and then, by start the same number of AsyncTask, performing the same operation but on different portions of data.
I am using executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, ...) in order to parallelize the execution of them.
I would like to know when every thread finishes its job so that combine all results and perform further operations.
How can I do?
You could also simply decrement a counter in a shared object as part of onPostExecute. As onPostExecute runs on the same thread (the main thread), you won't have to worry about synchronization.
UPDATE 1
The shared object could look something like this:
public class WorkCounter {
private int runningTasks;
private final Context ctx;
public WorkCounter(int numberOfTasks, Context ctx) {
this.runningTasks = numberOfTasks;
this.ctx = ctx;
}
// Only call this in onPostExecute! (or add synchronized to method declaration)
public void taskFinished() {
if (--runningTasks == 0) {
LocalBroadcastManager mgr = LocalBroadcastManager.getInstance(this.ctx);
mgr.sendBroadcast(new Intent("all_tasks_have_finished"));
}
}
}
UPDATE 2
According to the comments for this answer, OP is looking for a solution in which he can avoid building a new class. This can be done by sharing an AtomicInteger among the spawned AsyncTasks:
// TODO Update type params according to your needs.
public class MyAsyncTask extends AsyncTask<Void,Void,Void> {
// This instance should be created before creating your async tasks.
// Its start count should be equal to the number of async tasks that you will spawn.
// It is important that the same AtomicInteger is supplied to all the spawned async tasks such that they share the same work counter.
private final AtomicInteger workCounter;
public MyAsyncTask(AtomicInteger workCounter) {
this.workCounter = workCounter;
}
// TODO implement doInBackground
#Override
public void onPostExecute(Void result) {
// Job is done, decrement the work counter.
int tasksLeft = this.workCounter.decrementAndGet();
// If the count has reached zero, all async tasks have finished.
if (tasksLeft == 0) {
// Make activity aware by sending a broadcast.
LocalBroadcastManager mgr = LocalBroadcastManager.getInstance(this.ctx);
mgr.sendBroadcast(new Intent("all_tasks_have_finished"));
}
}
}
You should use a CountDownLatch. Here the documentation with examples:
java.util.concurrent.CountDownLatch
Basically you give a reference of CountDownLatch to your threads, and each of them will decrement it when finished:
countDownLatch.countDown();
The main thread will wait on the termination of all threads using:
countDownLatch.await();
First, add this class to your project
public abstract class MultiTaskHandler {
private int mTasksLeft;
private boolean mIsCanceled = false;
public MultiTaskHandler(int numOfTasks) {
mTasksLeft = numOfTasks;
}
protected abstract void onAllTasksCompleted();
public void taskComplete() {
mTasksLeft--;
if (mTasksLeft==0 && !mIsCanceled) {
onAllTasksCompleted();
}
}
public void reset(int numOfTasks) {
mTasksLeft = numOfTasks;
mIsCanceled=false;
}
public void cancel() {
mIsCanceled = true;
}
}
Then:
int totalNumOfTasks = 2; //change this to the number of tasks that you are running
final MultiTaskHandler multiTaskHandler = new MultiTaskHandler(totalNumOfTasks) {
#Override
protected void onAllTasksCompleted() {
//put the code that runs when all the tasks are complete here
}
};
Then in each task - when completed, add the line: multiTaskHandler.taskComplete();
Example:
(new AsyncTask<Void,Void,Void>() {
#Override
protected Void doInBackground(Void... voids) {
// do something...
return null;
}
#Override
protected void onPostExecute(Void aVoid) {
multiTaskHandler.taskComplete();
}
}).execute();
You can use multiTaskHandler.cancel() if you want to cancel the code that runs when all the tasks have completed. For instance - if you have an error (don't forget to also cancel all the other tasks).
* This solution will not pause the main thread!
Another Option could be to store all your new threads in an Array.
Then you could iterate over the Array and wait with thread[i].join for the thread to finish.
see join()
http://developer.android.com/reference/java/lang/Thread.html#Thread(java.lang.Runnable)
When the Iteration is finished all your threads are done and you can work on
RX Merge operator is your friend.
Get rid of AsyncTark is slower than RX and you cannot handle Errors
Let's say that I have an algorithm that does something for a given parameter. If the algorithm runs longer than 100 miliseconds then I want to stop it and try again for a different parameter.
I posted below the code that would test the algorithm for a random parameter... and how I think the code might look like:
public class StopThread {
private Lock lock = new ReentrantLock();
public static void main(String... args) {
System.out.println("Starting threads...");
(new StopThread()).startThreads(100);
}
private void startThreads(int nrOfThreads) {
for (int i = 0; i < nrOfThreads; i++) {
startThread(i, (long) (Math.random() * 10000000000l));
System.out.println("Started thread number " + (i + 1));
}
}
private void startThread(final int number, final long load) {
Thread workerThread = new Thread() {
#Override
public void run() {
try {
lock.lock();
doAlgorithmWork(load);
} finally {
System.out.println("Thread " + (number + 1) + " finished...");
lock.unlock();
}
}
};
Thread timerThread = new Thread() {
#Override
public void run() {
try {
sleep(100);
} catch (InterruptedException e) {
}
}
};
workerThread.start();
timerThread.start();
do {
if (!workerThread.isAlive() || !timerThread.isAlive()) {
workerThread.stop();
timerThread.stop();
}
} while (!workerThread.isAlive() && !timerThread.isAlive());
}
protected void doAlgorithmWork(long load) {
while (load-- > 0) {
}
}
}
I feel like this question should already have an answer, but what I found until now seemed complicated and I didn't know how to use it. I'm not that knowledgeable with threads and I would appreciate if you could post some code.
A very simple solution would look like this:
private void startThreads(int nrOfThreads) {
for (int i = 0; i < nrOfThreads; i++) {
Thread worker = new Thread() {
#Override
public void run() {
doAlgorithmWork((long) (Math.random() * 10000000000l));
}
}
worker.start();
worker.join(100); //block until either the thread is done, or 100ms passed
if (worker.isAlive()) worker.stop(); //if thread is still alive, stop it
}
}
This will achieve your goal, but suffers from a number of "drawbacks"
It is single threaded (that is, all calls to doAlgorithm execute one after another, instead of in parallel, so you are only using a single core of your machine);
It uses the discouraged Thread.stop() method. A preferred approach is to instead have a "stop" flag which is set to true (in place of the stop() call), and which is also constantly checked for in doAlgorith;
It creates a new thread for each doAlgorithm call (instead of reusing a single thread), which is "wasteful", but for your case probably has little practical implications
UPDATE:
In order to avoid the deprecated stop() call, you will need to add a flag to your worker thread, creating a separate class like this:
public class Worker implements Runnable {
private volatile boolean stopped = false;
public void stop() {
stopped = true;
}
#Override
public void run() {
doAlgorithmWork((long) (Math.random() * 10000000000l));
}
private void doAlgorithmWork(long load) {
while (!stopped && load-- > 0) {
//calculation
}
}
}
Then your runner looks like this:
private void startThreads(int nrOfThreads) {
for (int i = 0; i < nrOfThreads; i++) {
Thread worker = new Thread(new Worker());
worker.start();
worker.join(100); //block until either the thread is done, or 100ms passed
if (worker.isAlive()) worker.stop(); //if thread is still alive, stop it
}
}
You could also create a constructor for Worker which accepts the load value (instead of having it generated inside the Worker itself).
Note that if the calculation inside doAlgorithm() is too time-consuming, the thread may run for more than 100ms (since it always completes each calculation within the loop). If this is an issue, then your alternative is to interrupt the thread instead (calling worker.interrupt() will cause an InterruptedException to be thrown within the run() method).
I have this sittuation:
3 public methods, 2 are commands and 1 check inputs and will start command1 or command2 in thread. My question is how i can do that?
public void blablabla() {
input = get_user_input;
if(input == 1) {
start thread with command1
} else {
start thread with command2
}
}
public void command1() {
// do action
}
public void command2() {
// do action2
}
I think its impossible start a thread with method directly but using Runnable i can do that. I was thinking if its good choice and great idea for performance declare command1 and command2 are static runnable on class and use this runnables to start thread. Doing this as static runnable it will spend more memory than a method ?
Thanks!
you can use Asyn thread. try this below example
private class GetExampleDetails extends AsyncTask<String, Void, Void> {
private ProgressDialog dialog = new ProgressDialog(ExpensesListView.this);
String strMsg = null;
protected void onPreExecute() {
this.dialog.setMessage("Loading.....");
this.dialog.setCanceledOnTouchOutside(false);
this.dialog.show();
}
// automatically done on worker thread (separate from UI thread)
protected Void doInBackground(final String... a) {
try
{
//Write your code. which one do backround
}
catch(Exception ex)
{
ex.printStackTrace();
}
return null;
}
// can use UI thread here
protected void onPostExecute(final Void unused) {
if (this.dialog.isShowing()) {
this.dialog.dismiss();
this.dialog = null;
}
}
}//Endtask
check this one. i think this help you