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
Related
I'm using a few services inheriting from the AbstractScheduledService, which get managed by a ServiceManager. Everything works fine, but now, there's a service whose runOneIteration takes a rather long time, and as the result, my process takes too long to terminate (more than five seconds).
There are other services inheriting from AbstractExecutionThreadService, which had a similar problem, which I could solve via
#Override
protected final void triggerShutdown() {
if (thread != null) thread.interrupt();
}
and storing private volatile thread in the run method. However, there's no triggerShutdown for AbstractScheduledService as stated in this issue.
I already considered alternatives like making runOneIteration do less work, but it's both ugly and inefficient.
I can't override stopAsync as it's final and I can't see anything else. Is there a hook for doing something like this?
Can you work with this? Was there any reason you couldn't add a triggerShutdown yourself?
class GuavaServer {
public static void main(String[] args) throws InterruptedException {
GuavaServer gs = new GuavaServer();
Set<ForceStoppableScheduledService> services = new HashSet<>();
ForceStoppableScheduledService ts = gs.new ForceStoppableScheduledService();
services.add(ts);
ServiceManager manager = new ServiceManager(services);
manager.addListener(new Listener() {
public void stopped() {
System.out.println("Stopped");
}
public void healthy() {
System.out.println("Health");
}
public void failure(Service service) {
System.out.println("Failure");
System.exit(1);
}
}, MoreExecutors.directExecutor());
manager.startAsync(); // start all the services asynchronously
Thread.sleep(3000);
manager.stopAsync();
//maybe make a manager.StopNOW()?
for (ForceStoppableScheduledService service : services) {
service.triggerShutdown();
}
}
public class ForceStoppableScheduledService extends AbstractScheduledService {
Thread thread;
#Override
protected void runOneIteration() throws Exception {
thread = Thread.currentThread();
try {
System.out.println("Working");
Thread.sleep(10000);
} catch (InterruptedException e) {// can your long process throw InterruptedException?
System.out.println("Thread was interrupted, Failed to complete operation");
} finally {
thread = null;
}
System.out.println("Done");
}
#Override
protected Scheduler scheduler() {
return Scheduler.newFixedRateSchedule(0, 1, TimeUnit.SECONDS);
}
protected void triggerShutdown() {
if (thread != null) thread.interrupt();
}
}
}
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 need to make a generic SwingWorker process to use it in all my program.
My class is like this:
public class LoadingSwingWorker extends SwingWorker<Integer, Integer> {
private WaitingDiag diag;
private Statistics st = new Statistics();
public LoadingSwingWorker(GraphEditor editor, Statistics st) { //st variable
this.st = st;
Window mainWindow = SwingUtilities.windowForComponent(editor
.getGraphComponent().getParent());
diag = new WaitingDiag(mainWindow, "Loading data...");
}
#Override
protected Integer doInBackground() throws Exception {
st.loadInitialData(); //st method
return 42;
}
#Override
protected void done() {
diag.dispose();
}
public void openDiag() {
diag.setVisible(true);
}
}
For all my program, I may need to create SwingWorker classes as much as I need for long_time tasks (st variable in that case), is not possible to implement generic one
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.
Hi I am trying to make a multiplayer game where it would find the opponent in another thread, but I am not sure why the code running in the thread does not update the model in the main class...
Here is the code in the main class. The call to the LoadTask starts another thread
// Start model, passing number of words, user name, and selected animal
model = new MultiPlayerModel(NUM_WORDS, username, anmID);
model.addObserver(this);
new LoadTask().execute();
setContentView(R.layout.activity_multi_player);
initialDisplay(animal, background, oppAnimal);
Here is the code for the thread class
private class LoadTask extends AsyncTask<Void, Integer, Void> {
// called before running code in a separate thread
private boolean quitFlag;
#Override
protected void onPreExecute() {
progressDialog = ProgressDialog.show(MultiPlayer.this,"Finding a Game...",
"Searching for opponent, please wait...", false, false);
}
#Override
protected Void doInBackground(Void... params) {
synchronized (this) {
try {
model.beginMatchMaking();
model.setWordsList();
// Get the opponent's animal from the model
oppAnimal = reverseDrawable(model.getOpponentAnimal());
// Display the multiplayer screen
} catch (InternetConnectionException e) {
e.fillInStackTrace();
quitFlag = true;
error(States.error.CONNECTION);
return null;
} catch (EmptyQueueException e) {
e.fillInStackTrace();
quitFlag = true;
error(States.error.NOOPPONENT);
return null;
} catch (InternalErrorException e) {
e.fillInStackTrace();
quitFlag = true;
error(States.error.INTERNAL);
return null;
}
}
return null;
}
#Override
protected void onPostExecute(Void result) {
if (!quitFlag) {
progressDialog.dismiss();
gameTimer = new GameTimer(START_TIME, INTERVAL);
gameTimer.start();
}
}
}
And it segfaults on initialDisplay after the thread is called because the fields in model class were not updated at all. it acts as though it was just created and nothing was done to it
I'm not sure about AsyncTask class
but if it's properly configurated Thread and next line
new LoadTask().execute();
will start this thread properly, in this case thread will execute inparallel but usualy after lines:
setContentView(R.layout.activity_multi_player);
initialDisplay(animal, background, oppAnimal);
to prove it you may print messages main methods.
To solve it you may simply add next line after starting thread:
new LoadTask().execute();
Thread.sleep(100)