class A
{
public void func()
{
new Thread()
{
public void run()
{
// statements
}
} .start();
new Thread()
{
public void run()
{
// statements
}
} .start();
new Thread()
{
public void run()
{
// statements
}
} .start();
new Thread()
{
public void run()
{
// statements
}
} .start();
}
}
Here, I'm trying the first two threads (say pair A) to run concurrently and the next two threads (say pair B) to run concurrently only after pair A has finished executing.
Also if anybody can explain if it can be achieved via java.util.concurrent or threadgroup. I'll really appreciate any help done.
public void func()
{
Thread a = new Thread()
{
public void run()
{
// statements
}
}
Thread b = new Thread()
{
public void run()
{
// statements
}
}
a.start();
b.start();
a.join(); //Wait for the threads to end();
b.join();
new Thread()
{
public void run()
{
// statements
}
} .start();
new Thread()
{
public void run()
{
// statements
}
} .start();
}
You can use a CountDownLatch to wait until a certain number of threads call countDown(), at which point the main thread can then continue. You will have to make some alterations to your threads -- namely, you'll need to pass them the latch, and you'll need to have them call latch.countDown() when they are done with their jobs so the latch's count will eventually reach 0.
So your main class would look something like:
final CountDownLatch latch = new CountDownLatch(2); // Making this final is important!
// start thread 1
// start thread 2
latch.await(); // Program will block here until countDown() is called twice
// start thread 3
// start thread 4
And your threads would look something like:
new Thread() {
public void run() {
// do work
latch.countDown()
}
}
And only once the first two threads finish will the latch allow the main thread continue and start the other two threads.
Related
I have these two methods for creating and stopping a thread. However the thread still keeps running, even after the first method is called. (I'm creating an object of the class and calling them from another class).
private Thread thread;
public void stopAlarm() {
Log.i(LOG_TAG, "stopAlarm called");
sendAlarm = false;
if (!thread.equals(null)) {
try {
thread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public void triggerAlarm() {
Runnable alarmTest = new Runnable() {
#Override
public void run() {
while (sendAlarm) {
Log.i(LOG_TAG, String.valueOf(sendAlarm));
}
}
};
thread = new Thread(Test);
thread.start();
}
When stopAlarm is called the thread is always null, although it is called after triggerAlarm is called (thread is running).
Your problem is caused by thread scope. Thread scope is created when you create a thread with same variables in the scope but you can't change these variables from outside world. Best practice for managing runnables in android is to use Handler.
Handler handler = new Handler();
Runnable alarmTest = new Runnable() {
#Override
public void run() {
Log.i(LOG_TAG, String.valueOf(sendAlarm));
handler.post(alarmTest, 5000); //wait 5 sec and run again
//you can stop from outside
}
};
after definitions, in order to start the runnable:
handler.post(alarmTest,0); //wait 0 ms and run
in order to stop the runnable:
handler.removeCallbacks(alarmTest);
EDIT: wait statement with loop
EDIT: Complete solution
Handler handler = new Handler();
Runnable alarmTest = new Runnable() {
#Override
public void run() {
Log.i(LOG_TAG, String.valueOf(sendAlarm));
handler.post(alarmTest, 5000); //wait 5 sec and run again
//you can stop from outside
}
};
public void stopAlarm() {
Log.i(LOG_TAG, "stopAlarm called");
handler.removeCallbacks(alarmTest);
}
public void triggerAlarm() {
handler.post(alarmTest,0); //wait 0 ms and run
}
Depending on your OS you may find making your thread volatile may fix this.
private volatile Thread thread;
However - there are better ways to do this. One very useful one is using a small (just one entry) BlockingQueue which is polled by the running thread.
// Use a BlockingQueue to signal the alarm to stop.
BlockingQueue<String> stop = new ArrayBlockingQueue<>(1);
public void stopAlarm() {
stop.add("Stop");
}
public void triggerAlarm() {
new Thread(() -> {
try {
while (stop.poll(1, TimeUnit.SECONDS) == null) {
// Stuff
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}).start();
}
Clearly you will have to manage edge cases like where someone calls stopAlarm when no alarm is running.
class Test {
boolean isFirstThread = true;
private synchronized void printer(int threadNo) {
if(isFirstThread) {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
isFirstThread = false;
System.out.println(threadNo);
}
public void starter() {
new Thread(){
#Override()
public void run() {
printer(0);
}
}.start();
new Thread(){
#Override()
public void run() {
printer(1);
}
}.start();
new Thread(){
#Override()
public void run() {
printer(2);
}
}.start();
new Thread(){
#Override()
public void run() {
printer(3);
}
}.start();
}
}
In the above code, when i call starter from main. I have created four new Threads to call a synchronized function. I know the order of execution of the threads can't be predicted. Unless they all wait for some time, so that first thread can finish and come out of the synchronized block. In which case I expect all threads to be held in a queue so i expected the answer as
0
1
2
3
But consistently(I ran the program more than 20 times) I was getting the output as
0
3
2
1
Which means that the threads are being held in a stack instead of a queue. Why is it so? Every answer in the google result says it is a queue but I am getting it as a stack. I would like to know the reason behind for holding the threads in stack(which is counter intuitive) instead of queue?
The order in which threads start is up to the OS, it is not specified in the Java Language Spec. You call start in the main thread, but when the new thread gets allocated and when it begins processing its Runnable or run method is left to the OS' scheduler to decide.
Be careful not to rely on the order in which threads happen to start.
Today I was creating one timeout job using TimerTask but fell in to a new problem where i have a static volatile boolean variable flag. My understanding is as soon as value of this variable get changed it is notified by all running thread. But when I ran this program I got below output which is not acceptable.
O/P:
--------------
--------------
DD
BB
Exiting process..
CC
My expectation is my last print should be Exiting process.. Why is this strange behavior?
My code is:
public class TimeOutSort {
static volatile boolean flag = false;
public static void main(String[] args) {
Timer timer = new Timer();
timer.schedule(new TimerTask() {
#Override
public void run() {
flag = true;
System.out.println("Exiting process..");
// System.exit(0);
}
}, 10 * 200);
new Thread(new Runnable() {
#Override
public void run() {
while (!flag)
System.out.println("BB");
}
}).start();
new Thread(new Runnable() {
#Override
public void run() {
while (!flag)
System.out.println("CC");
}
}).start();
new Thread(new Runnable() {
#Override
public void run() {
while (!flag)
System.out.println("DD");
}
}).start();
}
}
Edit: How can i achieve this ?
volatile pretty much means that each time a thread accesses a variable it must ensure to use the version visible to each thread (i.e. no per-thread caching).
This doesn't force the CC-printing thread to actually get to run immediately after the flag has been set to true. It's entirely possible (especially on a single-core machine) that one thread sets the flag and prints the message before the CC-printing thread even had a chance to run.
Also: note that printing to System.out involves acquiring a lock (somewhere inside the println() call), which can modify the multi-threaded behaviour of test code.
Threads can execute code in any order
thread BB: while (!flag) // as flag is false
thread Main: flag = true;
thread Main: System.out.println("Exiting process..");
thread BB: System.out.println("BB");
My expectation is my last print should be Exiting process..
Threads are designed to run concurrently and independently. It would be surprising if this was always the last statement because you can't be sure where each thread is when you set the flag.
The thread that prints "CC" happened not to receive any CPU time until after your thread that prints "Exiting process..." printed that. This is expected behavior.
It's not volatile not working (if it were not, some of your threads would not have stopped). It's about the order of execution of instructions in the different threads, and this is random (depends on OS scheduling) unless you explicitly synchronize the loops at intermediate steps.
To add an alternative phrasing to the explanations you got: in your sample output, the thread that prints "CC" got suspended (somewhere) "between" the lines while (!flag) and System.out.println(). Which means that after it wakes up, the println() executes before the next check of the flag. (It also won't get woken up just because you change the flag value, but because some other thread blocks or uses up its time slice.)
i didn't test it , but you may achieve it like this
public class TimeOutSort {
static volatile boolean flag = false;
public static void main(String[] args) {
Timer timer = new Timer();
timer.schedule(new TimerTask() {
#Override
public void run() {
synchronized(flag){
flag = true;
notifyAll();
}
}
}, 10 * 200);
new Thread(new Runnable() {
#Override
public void run() {
synchronized(flag){
if(!flag)
{
wait();
}
System.out.println("BB");
}
}
}).start();
new Thread(new Runnable() {
#Override
public void run() {
synchronized(flag){
if(!flag)
{
wait();
}
System.out.println("CC");
}
}
}).start();
new Thread(new Runnable() {
#Override
public void run() {
synchronized(flag){
if(!flag)
{
wait();
}
System.out.println("DD");
}
}
}).start();
}
}
I have a JRuby engine which evaluates some scripts and I want to close the thread if it takes more than 5 seconds.
I tried something like this:
class myThread extends Thread{
boolean allDone = false;
public void threadDone() {
allDone = true;
}
public void run() {
while(true) {
engine.eval(myScript);
if(allDone)
return;
}
}
(...)
th1 = new myThread();
th1.start();
try {
Thread.sleep(5000);
if(th1.isAlive())
th1.threadDone();
} catch(InterruptedException e) {}
if(th1.isAlive())
System.out.println("Still alive");
I also tried to kill the thread with th1.stop() or th1.interrupt() but the value retured by th1.isAlive() method is always true.
What can I do?
I want to add that myScript could be "while(1) do; end" and I cannot wait until it's completed. So I want to prevent scripts like that and kill the thread if it takes more than 5 seconds.
Another solution would be to use the built-in mechanism to interrupt threads:
public void run() {
while (!Thread.currentThread().isInterrupted()) {
engine.eval(myScript);
}
}
...
th1 = new myThread();
th1.start();
try {
Thread.sleep(5000);
th1.interrupt();
}
This way, no need for an allDone field, and no risk in failing to synchronize.
To make your Thread stoppable you might want something like.
class MyTask implements Runnable {
public void run() {
try {
engine.eval(myScript);
} catch(ThreadDeath e) {
engine = null; // sudden death.
}
}
}
You can call Thread.stop(), but I suggest you read the warnings on this method first.
If you want a thread to run for up to 5 seconds, the simplest solution is for the thread to stop itself.
class MyTask implements Runnable {
public void run() {
long start = System.currentTimeMillis();
do {
engine.eval(myScript);
} while(System.currentTimeMillis() < start + 5000);
}
}
This assumes you want to run engine.eval() repeatedly. If this is not the case you may have to stop() the thread. It is deprecated for a good reason but it might be your only option.
I have a simple Question:
I have a Thread named rlMF. I created it this way:
public Thread rlMF = new Thread(new Runnable() {
public void run() {
reloadMissingFiles();
stopTh();
}
public void stopTh() {
activityStopped = true;
}
});
Now i want to call the stopTh Function from outer Thread. Why can't i simply call rlMF.stopTh(); and what can i do else?
Example:
protected void onPause() {
Log.d("Info", "destroying...");
activityStopped = true;
rlMF.stopTh();
super.onPause();
}
Is not working...
Because the interface accessible is from Thread. In order to have you method accessible from out, you need to specify a type that exposes this method.
And if you take a look carefully the method is implemented in the instance of Runnable. Not even in Thread.
You could have something like this if you really need to access the Runnable object:
class MyRunnable implements Runnable {
public void run() {
...
}
public void fooBar() {
...
}
}
public void someMethod() {
MyRunnable myRunnable = new MyRunnable();
Thread thread = new Thread(myRunnable);
...
myRunnable.fooBar();
...
}
An example for Francisco approach, besides what you are trying to achieve. Maybe this can point you in the right direction
public class CustomRun implements Runnable {
public void run() {
reloadMissingFiles();
stopTh();
}
public void stopTh() {
activityStopped = true;
}
}
In your Code
// start thread with custom runner
CustomRun runner = new CustomRun();
new Thread(runner).start();
// call your stopTh method on CustomRun class
protected void onPause() {
Log.d("Info", "destroying...");
activityStopped = true;
runner.stopTh();
super.onPause();
}
Your goal is to interrupt the thread from onPause. There are several ways to do it, but essentially, you will need to include some interruptibility in reloadMissingFiles.
Option 1
You can use a boolean flag like you did - you need to declare it as volatile to make sure the changes are visible across threads:
private volatile boolean activityStopped = false;
public void reloadMissingFiles() {
while (!activityStopped) {
//load small chunks so that the activityStopped flag is checked regularly
}
}
public Thread rlMF = new Thread(new Runnable() {
public void run() {
reloadMissingFiles(); //will exit soon after activityStopped has been set to false
}
});
protected void onPause() {
//This will stop the thread fairly soon if the while loop in
//reloadMissingFiles is fast enough
activityStopped = true;
super.onPause();
}
Option 2 (better approach)
I don't know what you do in reloadMissingFiles, but I suppose it is some sort of I/O operations, which are generally interruptible. You can then have an interruption policy where you stop as soon as an InterruptedException is caught:
public void reloadMissingFiles() {
try {
//use I/O methods that can be interrupted
} catch (InterruptedException e) {
//cleanup specific stuff (for example undo the operation you started
//if you don't have time to complete it
//then let the finally block clean the mess
} finally {
//cleanup (close the files, database connection or whatever needs to be cleaned
}
}
public Thread rlMF = new Thread(new Runnable() {
public void run() {
reloadMissingFiles(); //will exit when interrupted
}
});
protected void onPause() {
runner.interrupt(); //sends an interruption signal to the I/O operations
super.onPause();
}
Note: you can also read this article for a more in depth version of it.