I am a beginner and I was analyzing this java code:
// t is a thread running
while (true) {
try {
t.join();
} catch (InterruptedException e) { e.printStackTrace(); }
break;
}
t=null;
What I am asking is: is there a need to put that inside an infinite loop? Because as I see the loop will run only once i.e due to that break statement. I need some explanation please.
No, there's no need. Your observation is correct, the loop will be executed only once.
So the OP-posted code is equivalent to the following code.
// t is a thread running
try {
t.join();
} catch (InterruptedException e) { e.printStackTrace(); }
t=null;
Code posted by OP:
// t is a thread running
while (true) {
try {
t.join();
} catch (InterruptedException e) { e.printStackTrace(); }
break;
}
t=null;
As everyone has already pointed out, the code is incorrect as it stands.
The loop, however is necessary!
The correct code looks like this:
while (true) {
try {
t.join();
break;
} catch (InterruptedException e) { e.printStackTrace(); }
}
t = null;
Without the loop, it is possible for t to be set to null, before the current thread successfully joins it.
t.join(); waiting the finishing of thread.
After that, loop is broken by your "break".
=> always loop only 1 time => no need loop and break, only need t.join();
No need to have a while loop, because t.join() waits for the thread to die.
is like a loop already, in the program at the line of t.join() the program will be blocked while the thread is not dead.
The correct code is:
// t is a thread running
try {
t.join();
} catch (InterruptedException e) { e.printStackTrace(); }
t=null;
Here you have an example :
http://www.tutorialspoint.com/java/lang/thread_join.htm
Loop is not necessary!.
It is said that thread t is already started. Therefore it makes no sense "t=null". Thread t is already started and it will finish its job. You can use t.join() without while loop. In this context while loop does not make sense. The join method allows one thread to wait for the completion of another. If t is a Thread object whose thread is currently executing,
t.join();
causes the current thread(main thread in below example) to pause execution until t's thread terminates.Run following code snippet and know the ropes.
public class Main {
public static void main(String[] args) {
Thread t=new Thread(
new Runnable() {
public void run() {
for (int i = 0; i < 100; i++) {
System.out.println(Thread.currentThread().getName()+"--"+i);
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
});
t.start();
try {
t.join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
t = null; // no sense, t is already started
for (int i = 0; i < 100; i++) {
System.out.println(Thread.currentThread().getName()+"--Thread--"+i);
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
Related
I'm trying to create a thread and then interrupt it. But it doesn't stop and cause exception. Can anybody explain what am I doing wrong? Thanks.
public class Test {
public static void main(String[] args) throws InterruptedException {
//Add your code here - добавь код тут
TestThread test = new TestThread();
test.start();
Thread.sleep(5000);
test.interrupt();
}
public static class TestThread extends Thread {
public void run() {
while (!this.isInterrupted()) {
try {
Thread.sleep(1000);
System.out.println("I did the Thread");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
According to javadocs:
A thread interruption ignored because a thread was not alive at the
time of the interrupt will be reflected by this method returning
false.
Since you sleep the thread for 1000ms, when you call test.interrupt(), thread is asleep, almost all the times. So InterruptedException will be thrown. Therefore you should exit the loop at the catch clause.
Include a break when you catch InterruptedException to exit while loop.
while (!this.isInterrupted()) {
try {
Thread.sleep(1000);
System.out.println("I did the Thread");
} catch (InterruptedException e) {
break;
}
}
The internal flag gets resetted after calling interrupt.
You have to call it again in your catch of the thread.
The topic was also covered in the Java Specialists Newsletter
In my example, after I caught the InterruptedException, I used
Thread.currentThread().interrupt() to immediately interrupted the
thread again. Why is this necessary? When the exception is thrown, the
interrupted flag is cleared, so if you have nested loops, you will
cause trouble in the outer loops
Something like this should work:
try {
Thread.sleep(1000);
System.out.println("I did the Thread");
} catch (InterruptedException e) {
this.interrupt();
// No need for break
}
This makes sure that the rest of the code is executed.
I have come up with following thread 'halo' to make it connect to db (redis, in this case) and in the event that server fails, would wait for a second and try again. In my unit test class, method is executing, and not long after new thread starts, server will fail. But then this new thread 'halo' is immediately shut down. What am I doing wrong?
// almost infinitely large number of sets, interrupted by server seg-fault
// you gotta try company methods
Thread halo = new Thread(new Runnable() {
#Override
public void run() {
int count = 0;
while (count < Integer.MAX_VALUE) {
if (JedisPoolFactory.getStatus()) {
try {
for (int i = 0; i < 10000; i++) {
master.set(String.format("key_%d", count), String.format("value_%d", count));
System.out.println(master.get(String.format("key_%d", count)));
count++;
}
} catch (JedisConnectionException igr) {
try {
Thread.sleep(1000);
} catch (InterruptedException ignore) {}
}
} else {
try {
Thread.sleep(1000);
} catch (InterruptedException ignrod) {}
}
}
}
});
halo.start();
try {
master.debug(DebugParams.SEGFAULT());
halo.join();
} catch (JedisConnectionException ignored) {
} catch (InterruptedException igr) {}
thread joining should be done outside of exceptions, when master goes segfault it invokes jedisconnectionexception.
Given code is working in doInBackground(). Where while loop is always true but i don't know how it calls other methods in catch.
Can someone explain me the technique and how can we benefit with this technique. I don't know how and when we get out of the loop.
doInBackground
if(isRunning)
{
while (true) //this loop should run always.
{
try
{
Thread.sleep(1L);
}
catch (InterruptedException ex)
{
Log.e("Testing Interuption", "error=" + ex.getMessage());
// some working here is also running
}
}
}
Can it call any statement after while or not? I mean can it also get out of while loop or not.
Edit
When did the Interuption Occur.It means when another AsyncTask is calling Thread.sleep(); it will interupt(means go to catch). Am I right?
I am calling Multiple AsyncTasks to set a CameraPreview using Bitmap.
#TargetApi(11)
public void start()
{
if (Build.VERSION.SDK_INT >= 11)
{
executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, new Void[0]);
return;
}
execute(new Void[0]);
}
The while (true) statement will never end, since there's nothing to break out of the loop, so no, it can not get out of the while loop. (Depends on what's in // some working here is also running though.)
The code in the catch statement is executed if another thread sends an interrupt to this thread. When the code has been executed under catch the while loop re-starts again.
If you want to break out of the while loop if an InterruptedException is received, add a break; statement inside the catch.
It can call anything, as long as you break out of your loop, like this:
if (isRunning) {
while (true) //this loop should run always.
{
try {
Thread.sleep(1L);
}
catch (InterruptedException ex) {
Log.e("Testing Interuption", "error=" + ex.getMessage());
// some working here is also running
break; // <--
}
}
doStuffAfterWhileLoop();
}
i wrote some code, which should help you to understand how it is working.
public class Test2 {
boolean doBreakOut = false;
public Test2() {
Runnable runnable = new Runnable() {
#Override
public void run() {
while (true) // this loop is running while
// !(doBreakOut == true && isInterrupted()).
{
try {
Thread.sleep(1L);
} catch (InterruptedException ex) {
// this is executed when interrupt() is called.
if (doBreakOut) {
break;
}
System.out.println(("Testing Interuption -> "
+ "error=" + ex.getMessage()));
}
}
System.out
.println("did leave loop, threat will shut down now.");
}
};
try {
Thread threat = new Thread(runnable);
threat.start();
// Thread.sleep(x) makes the main thread wait for x milliseconds
Thread.sleep(2000);
threat.interrupt();
Thread.sleep(2000);
threat.interrupt();
Thread.sleep(2000);
doBreakOut = true;
threat.interrupt();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
new Test2();
}
}
class myThreadRun implements Runnable
{
public void run() {
roo();
}
public synchronized void roo()
{
System.out.println("In thread before wait " + Thread.currentThread().getName());
try {
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
JOptionPane.showMessageDialog(null, "After wait in\n"+Thread.currentThread().getName());
System.out.println("In thread after wait " + Thread.currentThread().getName());
//notify();
}
public synchronized void foo()
{
notify();
}
}
public class ThreadingDemo {
public synchronized void Start()
{
System.out.println("Labamba");
myThreadRun mThRun = new myThreadRun();
Thread thread = new Thread(mThRun);
thread.start();
try {
Thread.sleep(1000);
} catch (InterruptedException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
//mThRun.foo(); //This works
//mThRun.notify(); //crash
//thread.notify();//crash
try {
thread.join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static void main(String[] args) {
new ThreadingDemo().Start();
}
This is simple code to demonstrate wait() and notify(),
In the myThreadRun class run() method just does wait() and foo() method does notify()
as indicated in the code above, if I do mThRun.notify() the program crashes, but mThRun.foo() runs the without a hitch and gives the much needed result. I need to know why?
You need to own the monitor for the object to all obj.wait() and obj.notify().
That is why it works when called within the synchronized block on mThRun but not outside. So if you put the mThRun.notify(); in a synchronized block, it works, like this:
synchronized (mThRun) {
mThRun.notify();
}
In your case you are getting an IllegalMonitorStateException.
Thrown to indicate that a thread has attempted to wait on an object's monitor or to notify other threads waiting on an object's monitor without owning the specified monitor.
Put another way, you don't hold the lock of the object you are trying to notify. Having the lock of a different object doesn't help.
When you use notify() and wait() you need to change a state and check for it. If you don't do this, you can find that either
notify() is called before wait() and the signal is lost
wait() wakes prematurely
You cannot assume notify/wait is a reliable messaging protocol.
I suggest you consider using the concurrency library which is a better choice in most cases from Java 5.0 (2004)
May be you are going very hard with wait/notify. Its very simple. what you need to know is which object is used for monitor lock. To make the same code working i have modified the same code: ( I have put MAK comment where i changed the code, hope its helpful)
class MyThreadRun implements Runnable {
public void run() {
roo();
}
public synchronized void roo() {
System.out.println("In thread before wait " + this);
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
JOptionPane.showMessageDialog(null, "After wait in\n" + Thread.currentThread().getName());
System.out.println("In thread after wait " + Thread.currentThread().getName());
}
}
public class ThreadingDemo {
public static void main(String[] args) {
MyThreadRun mThRun = new MyThreadRun();
System.out.println("Labamba: " +mThRun);
Thread thread = new Thread(mThRun);
thread.start();
try {
Thread.sleep(100);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
//mThRun.foo(); //This works //MAK: no sense
//mThRun.notify(); //crash //MAK: Need monitor lock
synchronized (mThRun) {
mThRun.notify();//crash //MAK: will work now
}
try {
thread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
I have a thread that is running and performing a task repeatedly. I've implemented a counter to show me the iterations of the task performed by the thread. Every now and then I see that the counter is stuck somewhere and it's not increasing anymore. I don't receive any error or exceptions. The application runs but it looks like the thread just stopped without me asking it.
I will add some code to show the thread execution:
notice the int "c" - thats the counter for iterations.
public void check() {
Thread check = new Thread() {
public void run() {
for (;;) {
EventQueue.invokeLater(new Runnable() {
public void run() {
// Update GUI here on EventQueue.
try {
Task.readTasks();
} catch (InvalidFormatException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if (NoteInfo == null || NoteInfo == "") {
btnViewNote.setEnabled(false);
} else {
btnViewNote.setEnabled(true);
}
textField.setText(Task.printNextTask);
c++;
lblCycle.setText("Cycle: " + c);
}
});
try {
Thread.sleep(5000);
// Task.initializeIt();
} catch (InterruptedException ie) {
break;
}
if (killcheck)
break;
}
}
};
check.start();
}
public static void stopChecking() {
killcheck = true;
progressBar.setValue(0);
textArea.setText("");
textField.setText("");
c = 0;
lblCycle.setText("Cycle: " + c);
}
The check thread gets interrupted by another thread. Print the stack trace in the catch block and verify it.
try {
Thread.sleep(5000);
// Task.initializeIt();
} catch (InterruptedException ie) {
// break; // just ignore it
}
I don't see the definitions of killcheck or c but it is possible that these have not been marked as volatile?
If multiple threads are reading and writing a shared value then there must be some sort of synchronization otherwise they could be dealing with stale values. You can either use one of the atomic classes such as AtomicBoolean or AtomicInteger, use the synchronized keyword, or mark the variable as volatile. All three would allow the main thread and the inner thread to see each other's changes to the shared fields.
volatile int c;
volatile boolean killcheck;
For posterity, here's how you use the atomic classes:
final AtomicInteger c = new AtomicInteger();
final AtomicBoolean killcheck = new AtomicBoolean();
...
c.incrementAndGet();
...
if (killcheck)
break;
...
killcheck.set(true);
...
c.set(0);