Hi all may such a code cause lag of process?
while(true)
if(!connected) break;
As we see it checks for condition all the time. Would it be faster if I set small sleep in each iteration.
The code runs on Android GingerBread.
EDIT:
It waits for other Thread to finish and set variable Connected to false. Variable connected is used like lock. thread usually finds it true and waits to be false. then sets to true and only changes it at the end.
I think it would be better to add small sleep in your loop, to free processor resources for other processes, especially on one-core processor.
I belive it could be like this:
while(connected) {
// do stuff...
Try something like this:
private Integer connected;
private ConnectedListener connectedListener;
public interface ConnectedListener {
public void onDisconnected();
}
private void startThreads() {
for (int i = 0; i < 10; i++) {
new Thread(new Runnable() {
#Override
public void run() {
synchronized (connected) {
connected++;
}
// do some random long work
synchronized (connected) {
connected--;
if (connected == 0 && connectedListener != null) {
//let the listener know that we are completely disconnected
connectedListener.onDisconnected();
}
}
}
}).start();
}
}
Related
I have a thread that I'd like to wait for events on. When this thread is notified, I'd like it to wake up and if it's been longer than REFRESH_TIME, then it will invalidate a view with a call to postInvalidate. Otherwise it will sleep for the time it takes to fall on the next REFRESH_TIME. Meanwhile, if other events try to notify it to draw, some flag should be set so that it immediately redraws again after the next REFRESH_TIME passes again. Otherwise, it will wait indefinitely until next notify (or requested to stop of course, but ignore that part for simplicity).
I was trying to develop this within a synchronized lock with wait and notify and it doesn't seem like I can use just that. WaitForSingleObject with a timeout comes to mind for c++, but in java I haven't had the chance to do something similar yet. What would one use for this that would best suit the problem?
If I get 100 notifications while running an update, I should treat them as a single notify and add just one more invalidate, falling REFRESH_TIME milliseconds after the next one. In other words. Updates cannot be missed.
Here's some incomplete code. How could I finish it?
public class ViewInvalidator extends Thread {
private View m_view;
Object lock = new Object();
boolean ready = false;
long m_refreshTimeMilliseconds;
boolean m_threadRequestedToStop = false;
public ViewInvalidator(View view, long refreshTimeMilliseconds) {
m_view = view;
m_refreshTimeMilliseconds = refreshTimeMilliseconds;
}
public void postInvalidate() {
synchronized(lock) {
ready = true;
lock.notifyAll();
}
}
public void stopThread() {
synchronized (lock) {
while(!ready)
lock.notifyAll();
}
}
#Override
public void run() {
long lastPostInvalidate = System.currentTimeMillis(), timeSince;
while(true) {
if (this.m_threadRequestedToStop)
break;
try {
synchronized (lock) {
while (!ready)
lock.wait();
}
} catch(InterruptedException e) {
System.out.println(e.getMessage());
e.printStackTrace();
break;
}
// someone just woke us up. Check if it was a request to stop. If it was, stop.
if (this.m_threadRequestedToStop)
break;
// if less time than our refresh time, sleep for the difference, then invalidate. Otherwise just invalidate.
timeSince = System.currentTimeMillis() - lastPostInvalidate;
if(timeSince < m_refreshTimeMilliseconds)
try {
Thread.sleep(m_refreshTimeMilliseconds - timeSince);
} catch(InterruptedException e) {}
m_view.postInvalidate();
}
}
Thanks a lot,
Mike
long lastPostInvalidate;
bool running;
bool valid;
public void f(){
if(running)if(!valid)synchronized(valid){valid=true;}
else {
running = true;
while(func()){};
running = false;
}
private bool func() {
synchronized (valid){valid = false;}
synchronized (lastPostInvalidate) {
long next = System.currentTimeMillis();
long x = next - timeSincelastPostInvalidate;
x = m_refreshTimeMilliseconds-x;
if(x>0)sleep(x);
m_view.postInvalidate();
timeSincelastPostInvalidate = next;
}return valid;
}
Forgot that use condition. It should actually have looked like this. That said, doing it this way could potentially lock your updating thread if you are expecting to frequently update mid-update, which would matter if you were also using those threads for other things. If you expect updates that frequently though, you might as well use the thread as you originally planned but not have it deactivate and just check every interval if it needs to run or not.
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 a class which processes something. I'm trying to run a number of instances of this class in parallel.
However, I'm not sure if in TaskManager.startAll(), when I call r.go(), whether this would cause r to start running in its own thread, or within the main thread?
The total execution time that I'm getting seems to be very high, and despite my attempts at optimizing, nothing seems to be having any effect. Also, if I run a profiler on my project in Netbeans, it shows all the threads as sleeping. So I'd like to know if I'm doing something wrong?
This is the structure of the class:
public class TaskRunner implements Runnable {
private boolean isRunning = false;
public void run() {
while(true) {
while (! running) {
try {
Thread.sleep(1);
} catch (Exception e) {
e.printStackTrace();
}
}
process();
}
}
public void go() {
isRunning = true;
}
public void stop() {
isRunning = false;
}
private void process() {
//Do some number crunching and processing here
}
}
Here's how these are being run / managed:
public class TaskManager {
private ArrayList<TaskRunner> runners = new ArrayList<>();
public TaskManager() {
for (int i = 0; i < 10; i++) {
TaskRunner r = new TaskRunner();
new Thread(r).start();
runners.add(r);
}
}
public void startAll() {
for (TaskRunner r : runners) {
r.go();
}
}
}
Indeed, you are not "doing it right." If you want to create a multi-threaded Java application, the place to start is with the java.util.concurrent package.
It appears from your code that you want to run ten tasks in parallel. I assume that after "number crunching and processing," you'll want to aggregate the results and do something with them in the main thread. For this, the invokeAll() method of ExecutorService works well.
First, implement Callable to do the work you show in your process() method.
final class YourTask implements Callable<YourResults> {
private final YourInput input;
YourTask(YourInput input) {
this.input = input;
}
#Override
public YourResults call()
throws Exception
{
/* Do some number crunching and processing here. */
return new YourResults(...);
}
}
Then create your tasks and run them. This would take the place of your main() method:
Collection<Callable<YourResults>> tasks = new List<>(inputs.size());
for (YourInput i : inputs)
tasks.add(new YourTask(i));
ExecutorService workers = Executors.newFixedThreadPool(10);
/* The next call blocks while the worker threads complete all tasks. */
List<Future<YourResult>> results = workers.invokeAll(tasks);
workers.shutdown();
for (Future<YourResult> f : results) {
YourResult r = f.get();
/* Do whatever it is you do with the results. */
...
}
However, I'm not sure if in TaskManager.startAll(), when I call r.go(), whether this would cause r to start running in its own thread, or within the main thread?
So my first comment is that you should make isRunning be volatile since it is being shared between threads. If the threads are not starting when it goes to true (or seem to be delayed in starting) then I suspect that's your problem. volatile provides memory synchronization between the threads so the thread that calls go() and makes a change to isRunning will be seen immediately by the thread waiting for the change.
Instead of spinning like this, I would use wait/notify:
// this synchronizes on the instance of `TaskRunner`
synchronized (this) {
// always do your wait in a while loop to protect against spurious wakeups
while (!isRunning && !Thread.currentThread().isInterrupted()) {
try {
// wait until the notify is called on this object
this.wait();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
e.printStackTrace();
}
}
Then in the go() method you should do the following. stop() would be similar.
public void go() {
synchronized (this) {
isRunning = true;
this.notifyAll();
}
}
Notice that you should handle thread interrupts carefully. Test for isInterrupted() in the while running loop and re-interrupt a thread when InterruptedException is thrown is always a good pattern.
The total execution time that I'm getting seems to be very high, and despite my attempts at optimizing, nothing seems to be having any effect. Also, if I run a profiler on my project in Netbeans, it shows all the threads as sleeping.
So although the threads are mostly sleeping, they are still each looping 1000 times a second because of your Thread.sleep(1). If you increased the time sleeping (after making isRunning be volatile) they would loop less but the right mechanism is to use the wait/notify to signal the thread.
Awful solution, terrible. first I highly recommend you start reading some tutorial like [this]
Second, if threads should wait for a signal to go for some job, so why just don't you wait them!!!!!, something like this
import java.util.ArrayList;
public class TaskManager
{
//////////////////////
public volatile static Signal wait=new Signal();
//////////////////////
private ArrayList<TaskRunner> runners = new ArrayList<>();
public TaskManager()
{
for (int i = 0; i < 10; i++)
{
TaskRunner r = new TaskRunner();
new Thread(r).start();
runners.add(r);
}
try {
Thread.sleep(1000);
startAll();
Thread.sleep(1000);
pauseAll();
Thread.sleep(1000);
startAll();
Thread.sleep(1000);
haltAll();System.out.println("DONE!");
}catch(Exception ex){}
}
public void startAll()
{
synchronized(wait){
wait.setRun(true);;
wait.notifyAll();
}
}
public void pauseAll(){
wait.setRun(false);
}
public void haltAll(){
for(TaskRunner tx:runners){tx.halt();}
}
public static void main(String[] args) {
new TaskManager();
}
}
class TaskRunner implements Runnable
{
private Thread thisThread;
private volatile boolean run=true;
public void run()
{
thisThread=Thread.currentThread();
while(run){
if(!TaskManager.wait.isRun()){
synchronized(TaskManager.wait)
{
if(!TaskManager.wait.isRun()){
System.out.println("Wait!...");
try
{
TaskManager.wait.wait();
}
catch (Exception e)
{
e.printStackTrace();
break;
}
}
}}
process();
}
}
private double r=Math.random();
private void process(){System.out.println(r);try {
Thread.sleep(10);
} catch (Exception e) {
// TODO: handle exception
}}
public void halt(){run=false;thisThread.interrupt();}
}
class Signal{
private boolean run=false;
public boolean isRun() {
return run;
}
public void setRun(boolean run) {
this.run = run;
}
}
in above sample, all runners works till the Signal run boolean is true, and simple TaskManager class set tit as false for every time it needs to pause the threads. and about the halt, it just set the shutdown(run) flag to false, and also interrupt the thread because of if thread is in wait state.
I hope I could prove your solution is like dream-on story, and also could explained enough about my solution.
have a good parallel application :)
I have a program which creates 10 threads, and each thread has an infinitely running while loop.
I need help to efficiently implement a Shutdown hook which can effectively STOP all the threads. Since I want to do a graceful shutdown each Thread should finish as soon as it finds the stop flag turned to TRUE.
public class SampleGSH implements Runnable{
private static boolean stop = false;
public static void main(String[] args) {
for(int i = 0; i < 10;i++) {
Thread t = new Thread(new SampleGSH(), "name"+i);
t.start();
}
}
#Override
public void run() {
Runtime.getRuntime().addShutdownHook(new Thread("shutdown thread") {
public void run()
{
System.out.println("*******");
synchronized (this)
{
System.out.println("Turning switch off");
stop = true;
}
}
});
synchronized (this) {
while(!stop)
{
//Some logic which should not be killed abruptly once it starts running, a graceful shut down will not allow this code to start
}
}
}
}
Any help will be truly appreciated.
I need help to efficiently implement a Shutdown hook which can effectively STOP all the threads.
If you have any fields that are shared between multiple threads, they need to be synchronized. In this case your stop should be volatile. Without this, there is nothing that ensures that the threads will see the value of stop change to true. See this tutorial for information about atomic access.
See: Using boolean var for stopping threads
Couple other comments:
If you are starting a number of threads, you should consider using an ExecutorService
Your while loop is inside of a synchronized block. This does nothing and the stop field will not get memory synchronized since it gets updated externally while inside of the block.
Another way to stop a thread would be to interrupt() it. See this tutorial.
while (!thread.currentThread().isInterrupted()) {
...
}
...
t.interrupt();
Instead of a single static stop boolean, you could give every thread its own stop boolean. Then store all thread objects when creating them and set their stop boolean to true in the shutdown hook thread (which would be hooked in the main method).
Something like this:
import java.util.ArrayList;
import java.util.List;
public class SampleGSH extends Thread {
public boolean stop = false;
private static List<SampleGSH> threads = null;
public static void main(String[] args) {
threads = new ArrayList<SampleGSH>();
int numThreads = 10;
for (int i = 0; i < numThreads; i++) {
SampleGSH t = new SampleGSH();
threads.add(t);
t.start();
}
Runtime.getRuntime().addShutdownHook(new Thread("shutdown thread") {
public void run() {
System.out.println("*******");
for (SampleGSH t : threads) {
t.stop = true;
}
}
});
}
#Override
public void run() {
{
while (!stop) {
// Some logic which should not be killed abruptly once it starts
// running, a graceful shut down will not allow this code to
// start
}
}
}
}
Forget that addShutdownHook guff ... keep it simple ...
Make the static stop variable volatile ...
then add this method to SampleGSH ...
public void shutdown() {
stop = true;
}
then call it when you want to stop the threads!
Is there a way to wait for all Runnables submitted to the SWT UI Thread via asyncExec(...) to finish?
Background:
I have a long-running operation, which among other things is triggering events that in turn submit Runnables to the SWT UI thread via the asyncExec(...) instance method of Display.
The progress of the long-running operation is shown in a ProgressMonitorDialog, and I would like to close the dialog only after the UI thread has finished executing the Runnables.
Changing the calls from asyncExec(...) to syncExec(...) is not an option, as the latter is not desired when the events are triggered from other contexts.
org.eclipse.swt.widgets.Display.readAndDispatch() will process an event from the event queue and return false if there are no more events to process. But you probably don't want to use this as it processes an event.
asyncExec(*) is a FIFO queue (although OS graphics events supersede the asyncExecs), so you could do most of your long-running op processing and then place a final asyncExec in the queue:
final boolean[] done = new boolean[1];
Runnable r = new Runnable() {
public void run() {
done[0] = true;
}
};
// now wait for the event somehow. The brute force method:
while (!done[0]) {
Thread.sleep(200);
}
In theory, all of the other asyncExecs spawned from your long running op will be finished by the time you get to the last one.
EDIT: potential other option
Create your own org.eclipse.core.runtime.jobs.Job and then join() it at the end:
public static class RefCountJob extends Job {
public RefCountJob() {
super("REF_COUNT");
}
int count = 0;
public void increment() {
count++;
}
public void decrement() {
count--;
}
#Override
protected IStatus run(IProgressMonitor monitor) {
monitor.beginTask("WAITING", IProgressMonitor.UNKNOWN);
while (count > 0) {
Thread.sleep(200);
monitor.worked(1);
}
monitor.done();
return Status.OK_STATUS;
}
}
To use it, increment() it every time you are going to fire off events, and have them decrement it when they're done (You have to make sure they decrement it no matter what exception is thrown :-)
RefCountJob ref = new RefCountJob();
// ... do stuff, everybody increments and decrements ref
ref.increment();
// ... do more stuff
ref.increment();
// at the end of your long-running job
ref.schedule();
ref.join();
Thanks, I ended up with the following. I think it is a pretty clean solution. By the way I would upvote your answer if I had enough reputation for that :)
public class SWTThreadingUtils
{
public static void waitForAsyncExecsToFinish(Display display)
{
Object waitObj = new Object();
display.asyncExec(new DummyRunnable(waitObj));
synchronized (waitObj)
{
try {
waitObj.wait();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
private static class DummyRunnable implements Runnable
{
private Object waitObj;
public DummyRunnable(Object waitObj)
{
this.waitObj = waitObj;
}
#Override
public void run()
{
synchronized (waitObj)
{
waitObj.notify();
}
}
}
}