This is a simple example about creating a thread by extending the Thread class.
class Count extends Thread {
Count() {
super("my extending thread");
System.out.println("my new thread is started " + this);
start();
}
#Override
public void run() {
try {
for (int i = 0; i < 10; i++) {
System.out.println("count " + i);
Thread.sleep(1000);
}
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
System.out.println("my thread run is over");
}
}
}
public class Multi2 {
public static void main(String[] args) {
Count c = new Count();
try {
while (c.isAlive()) {
System.out.println("main thread is alive untill child thread is alive");
Thread.sleep(1500);
}
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
System.out.println("main thread is over");
}
}
}
And my output was this.
my new thread is started Thread[my extending thread,5,main]
main thread is alive untill child thread is alive
count 0
count 1
main thread is alive untill child thread is alive
count 2
main thread is alive untill child thread is alive
count 3
count 4
main thread is alive untill child thread is alive
count 5
main thread is alive untill child thread is alive
count 6
count 7
main thread is alive untill child thread is alive
count 8
main thread is alive untill child thread is alive
count 9
my thread run is over
main thread is over
My questions are,
01. How come main thread is alive untill child thread is aliveoutput printed before count 0
count 1
02.How come main thread is alive untill child thread is aliveoutput keep printing withing the output of run() method?
Please help me to figure this out.
Thank you.
Count has this line:
Thread.sleep(1000);
Your main program has this line:
Thread.sleep(1500);
Clearly, you're going to get 2 main prints for every 3 count prints. That's why 0 and 1 are next to each other.
As for why you see the main print before the count prints, you can see this:
Count c = new Count();
try {
while (c.isAlive()) {
System.out.println("main thread is alive untill child thread is alive");
Thread.sleep(1500);
You've fired off your c but until your JVM performs a context switch to actually run that thread, you might not see results. The truth is you may, on some systems, see your counter before that. Often, because it's so close to when it kicks off and hasn't yielded yet, you'll see the main print before the counter.
For your second part, your main thread is... keeps printing because it has a loop that tells it to print until your counter thread is no longer alive. They both use System.out so when you look at your console you see them both there.
Related
I am new to java programming and trying threading for the first time. I have created a thread to print the even numbers, and then a thread to print odd numbers. In the odd number thread there is a suspend() method after the number 11 to be printed. And after that there is another block to print odd numbers from 13 to 21. In main() I joined the 2 threads. In main function first I called thread t1(even number) and then joined it with thread t2(odd number). As there is suspend it will suspend the output after printing 11 it pauses there. But after that when i call t2.resume() that doesn't continue printing 13 to 21. Why it isn't printing the rest? and how can I make it resume?
Here's the code, please take a look:
class Hi extends Thread {
public void run(){
try{
for(int i=0; i<=10; i++){
System.out.println("1st: " + (2*i));
sleep(100);
}
} catch(Exception e){
System.out.println(e);
}
}
}
class Hello extends Thread {
public void run(){
try {
for(int i=0; i<=5; i++){
System.out.println("2nd: " +(2*i+1));
}
suspend();
System.out.println(" Resumes again");
for(int i=6; i<=10; i++){
System.out.println("2nd: " +(2*i+1));
}
} catch(Exception e){
System.out.println(e);
}
}
}
public class thread {
public static void main(String args[]){
Hi t1 = new Hi();
Hello t2 = new Hello();
t1.start();
try {
t1.join();
} catch (Exception e) {
}
t2.start();
t2.resume();
}
}
OUTPUT:
1st: 0
1st: 2
1st: 4
1st: 6
1st: 8
1st: 10
1st: 12
1st: 14
1st: 16
1st: 18
1st: 20
Exception in thread "main" 2nd: 1
java.lang.IllegalThreadStateException
2nd: 3
2nd: 5
2nd: 7
2nd: 9
2nd: 11
at java.base/java.lang.Thread.start(Thread.java:791)
at thread.main(thread.java:57)
After this the program isn't exiting, I have to exit the program manually (ctrl+c) in the terminal.
After this the program isn't exiting, I have to exit the program manually (ctrl+c) in the terminal.
Aside from the fact that you should not be using suspend() and resume(), I believe your problem is a classic race condition. The main thread is calling t2.start() and then t2.resume() but the thread is not suspended yet. The main thread throws an exception and then the t2 thread finishes its printing and calls suspend(). There is no one left to resume it so the thread never finishes and you have to control-c your program.
You should make a couple of change to your example code. First off use wait/notify instead of suspend(). For example, have the Hello thread do:
// t2 thread shouldn't use suspend which is deprecated for good reason
synchronized (this) {
wait();
}
Then in the main thread you need to loop until the thread is in a wait state before notify-ing it. Something like:
while (true) {
if (t2.getState() == State.WAITING) {
synchronized (t2) {
t2.notify();
}
break;
}
Thread.sleep(100);
}
These sorts of thread exercises where one thread is locked stepped with another (aside from a join() at the end) are a bad example of threading IMO.
Couple other comments. You should join() with the Hello thread at the end of your code, never catch Exception if you can help it since it hides exceptions that may be the source of problems (at least print them as #GhostCat recommended), and also always re-interrupt your threads when you catch InterruptedException:
try {
t2.join();
} catch (InterruptedException e) {
// always a good pattern
Thread.currentThread().interrupt();
e.printStackTrace();
}
when i call t2.resume() that doesn't continue printing 13 to 21. Why it isn't printing the rest?
#Gray answered that one. TLDR: Your main thread calls t2.resume() before your t2 thread calls suspend().
I am curious to know what Java version you are using. I'm running JDK11 on macOS, and I can't get your program to throw that java.lang.IllegalThreadStateException, but I'm guessing that in whatever JDK and OS you are using, the exception is thrown when your main thread tries to resume() a thread that isn't suspended.
how can I make it resume?
I would use a Semaphore.
Let the t2 thread wait to acquire() a "permit" from a semaphore, and let the main thread release() a permit to the semaphore at the appropriate time.
I changed your program by replacing the suspend() call with sem.acquire(), and by replacing the resume() call with sem.release(). I also threw a call to Thread.sleep() into the main thread before it releases the semaphore so that you can see the pause. Here's the whole thing:
import java.util.concurrent.Semaphore;
class Hi extends Thread { // This class is exactly the same as yours.
public void run(){
try{
for(int i=0; i<=10; i++){
System.out.println("1st: " + (2*i));
sleep(100);
}
} catch(Exception e){
System.out.println(e);
}
}
}
class Hello extends Thread {
private Semaphore sem; // new member variable
public Hello(Semaphore sem) { // new constructor to set the new member.
this.sem = sem;
}
public void run(){
try {
for(int i=0; i<=5; i++){
System.out.println("2nd: " +(2*i+1));
}
// Wait to "acquire" a permit from the semaphore. This won't
// return until the main thread "releases" a permit _to_ the
// semaphore.
sem.acquire();
System.out.println(" Resumes again");
for(int i=6; i<=10; i++){
System.out.println("2nd: " +(2*i+1));
}
} catch(Exception e){
System.out.println(e);
}
}
}
public class Wonk {
public static void main(String args[]){
// Create a semaphore that initially has 0 "permits."
Semaphore s = new Semaphore(0);
Hi t1 = new Hi();
Hello t2 = new Hello(s);
t1.start();
try {
t1.join();
} catch (Exception e) {
}
t2.start();
waitabit(5000); // Sleep 5 seconds, and then...
s.release(); // ...Release the Hounds!!
}
private static void waitabit(int numMilliseconds) {
try {
Thread.sleep(numMilliseconds);
}
catch (Exception e) {
e.printStackTrace();
}
}
}
I'm having trouble getting over 100 threads to run simultaneously. When I do a thread dump, I noticed that many of them are in parked status, i.e.
parking to wait for <0x00000000827e1760> (java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject).
The program runs fine with about 25 threads or less. Is there a way ti identify what's causing the concurrent lock, and/or prevent it? This was running in a fixed pool size of 200 using the Executor service.
Apologies for the lack of code - it's proprietary and there's a lot to be changed to obfuscated it.
Are you using some sort of ThreadPoolExecutor such as the ones provided by java.util.concurrent.Executors class? Perhaps you are facing a case of tasks being finished by silently uncaught exceptions. The dump fragment looks like an inactive pooled thread and one reason to get an inactive thread (which should be active) is an exception throwed up but surrounded by the default thread pool implementation.
LockSupport.park()
In thread pools, THREADS waiting for a TASK are locked out by LockSupport.park();. See java.util.concurrent.locks.AbstractQueuedSynchronizer source from openjdk :
public final void await() throws InterruptedException {
// code omitted
while (!isOnSyncQueue(node)) {
LockSupport.park(this);
if ((interruptMode = checkInterruptWhileWaiting(node)) != 0)
break;
}
// code omitted
}
It means that the TASK which the THREAD were executing finished (abruptaly or not) and now the thread is waiting for another task to execute (see java.util.concurrent.ThreadPoolExecutor openjdk source):
private Runnable getTask() {
// ...
Runnable r = timed ?
workQueue.poll(keepAliveTime, TimeUnit.NANOSECONDS) :
workQueue.take(); <== the thread is blocked here
// ...
}
As one can see, the thread is locked out in the call workQueue.take();.
Thus, shortly, threads in "parked status" are just waiting for new tasks after the previous ones have finished.
Why does my task is no longer running?
The most reasonable cause of a finished task is the regular end of the run(). The task flow finishes and then the task is released by the respective owner thread. Once the thread releases the task, it is ready to execute another task as long there is one.
A straightforward way to check this scenario is by logging something in the end of the run() method:
class MyRunnable implements Runnable {
public void run() {
while(/*some condition*/) {
// do my things
}
log.info("My Runnable has finished for now!");
}
}
If log a message is not enough you can call a method of another object instead.
Exceptions under the wood
Another (most) probable cause is an uncaught exception thrown during the task execution. Within a thread pool, an unchecked exception like this will abruptaly stop the method execution and (surprisely) be swallowed into a java.util.concurrent.FutureTask object. In order to avoid things like this, I use the following idiom:
class MyRunnable implements Runnable {
public void run() {
while(/*some condition*/) {
try {
// do my things
} catch (Throwable throwable) {
handle(throwable);
}
}
log.info("My Runnable has finished for now!");
}
private void handle(Throwable throwable) {
// ...
}
}
or depending on the logic/performance requirements I also use:
public void run() {
try {
while(/*some condition*/) {
// do my things
}
} catch (Throwable throwable) {
handle(throwable);
}
System.out.println("My Runnable has finished for now!");
}
The code below exemplify the issues commented here in action:
package mypocs;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadPoolExecutor;
public class ExceptionSwallowingInThreadPoolsPoC {
public static void main(String[] args) {
ThreadPoolExecutor threadPoolExecutor = (ThreadPoolExecutor) Executors.newFixedThreadPool(10);
final Object LOCK = new Object();
threadPoolExecutor.submit(() -> {
while (true) {
synchronized (LOCK) {
System.out.println("Thread 'A' never ends");
}
Thread.sleep(1000L);
}
});
threadPoolExecutor.submit(() -> {
int lifespan = 3;
while (lifespan > 0) {
synchronized (LOCK) {
System.out.println("Thread 'B' is living for " + lifespan + " seconds");
}
lifespan--;
try {
Thread.sleep(1000L);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("Thread 'B' finished");
});
threadPoolExecutor.submit(() -> {
int lifespan = 3;
while (lifespan > 0) {
synchronized (LOCK) {
System.out.println("Thread 'C' is living for " + lifespan + " seconds");
}
lifespan--;
if (lifespan < 1) {
throw new RuntimeException("lifespan reached zero");
}
try {
Thread.sleep(1000L);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("Thread 'C' finished");
});
while (true) {
try {
Thread.sleep(1000L);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (LOCK) {
System.out.println("==== begin");
System.out.println("getActiveCount: " + threadPoolExecutor.getActiveCount());
System.out.println("getCompletedTaskCount: " + threadPoolExecutor.getCompletedTaskCount());
System.out.println("getPoolSize: " + threadPoolExecutor.getPoolSize());
System.out.println("==== end");
}
}
}
}
The code should output something like:
Thread 'A' never ends
Thread 'B' is living for 3 seconds
Thread 'C' is living for 3 seconds
Thread 'C' is living for 2 seconds
==== begin
getActiveCount: 3
getCompletedTaskCount: 0
getPoolSize: 3
==== end
Thread 'B' is living for 2 seconds
Thread 'A' never ends
==== begin
getActiveCount: 3
getCompletedTaskCount: 0
getPoolSize: 3
==== end
Thread 'C' is living for 1 seconds
Thread 'B' is living for 1 seconds
Thread 'A' never ends
Thread 'B' finished
==== begin
getActiveCount: 1
getCompletedTaskCount: 2
getPoolSize: 3
==== end
Thread 'A' never ends
Thread 'A' never ends
...
The class (ConditionObject) you are referring to is used to lock objects from being accessed concurrently by multiple threads. The Javadoc doesn't describe the thread state you mention, but here is my guess:
Your locked object is being blocked by one thread so long, that the other threads start to pile up on the lock. Once the thread holding the lock releases it, the next thread continues the aquire the lock. Until that new thread has done his work, new threads pile up behing the lock.
If my guess is right, then could:
reduce the time that each thread spends in the lock, or
distribute the threads on different locked things (if your problem permits that), or
you use an implementation that doesn't require locking.
Without knowing your problem domain, I hope that the information above is enough to point you into some direction that might be of help for you.
I am not able to understand how the control is transferring from "Expl Thread" output statement to the "Main Thread" output statement.
package com.myjava.threads;
class MyRunnableThread implements Runnable {
public static int myCount = 0;
public MyRunnableThread() {
}
public void run() {
while (MyRunnableThread.myCount <= 10) {
try {
System.out.println("Expl Thread: " + (++MyRunnableThread.myCount));
Thread.sleep(100);
} catch (InterruptedException iex) {
System.out.println("Exception in thread: " + iex.getMessage());
}
}
}
}
public class RunMyThread {
public static void main(String a[]) {
System.out.println("Starting Main Thread...");
MyRunnableThread mrt = new MyRunnableThread();
Thread t = new Thread(mrt);
t.start();
while (MyRunnableThread.myCount <= 10) {
try {
System.out.println("Main Thread: " + (++MyRunnableThread.myCount));
Thread.sleep(100);
} catch (InterruptedException iex) {
System.out.println("Exception in main thread: " + iex.getMessage());
}
}
System.out.println("End of Main Thread...");
}
}
The output is:
Starting Main Thread...
Main Thread: 1
Expl Thread: 2
Main Thread: 3
Expl Thread: 4
Main Thread: 5
Expl Thread: 6
Main Thread: 7
Expl Thread: 8
Main Thread: 9
Expl Thread: 10
Main Thread: 11
End of Main Thread...
There is no control that is transferred... The threads are independently printing to the console every 100 milliseconds. Since the times are the same, then it appears they "take turns", but which "goes first" is not deterministic.
Change one of the Thread.sleep(100); values and you will see that one will take longer/shorter than the other to print.
how the control is transferring from "Expl Thread" output statement to the "Main Thread" output statement.
Control isn't being passed. Instead each thread is calling
Thread.sleep(100);
And as this is the same amount of time, they take turns. Change one of them to sleep(50) and you will see one prints messages twice as fast.
That is something the thread scheduler decides. When you start the thread, it will run parallel with the other threads that are already there. Its up-to the thread scheduler to decide the order and the time allotted to each thread.
There is no guarantee on the order of execution.
I am bit confused with the behaviour of thread.isInterrupted in the program below.
public class ThreadPractice {
public static void main(String args[]) throws InterruptedException {
Thread t = new Thread(new Runnable() {
#Override
public void run() {
try {
System.out.println("Starting thread..." + Thread.currentThread().getName());
Thread.sleep(10000);
System.out.println("Waking up");
}catch(InterruptedException e){
System.out.println("Thread is interrupted!!!");
Thread.currentThread().interrupt();
}
}
});
t.start();
Thread.sleep(2000);
t.interrupt();
//System.out.println(!t.isInterrupted());
while(!t.isInterrupted()){
System.out.println("Current thread not interrupted!!!");
}
}
}
When executing the above program as such, it prints,
Starting thread...Thread-0
Thread is interrupted!!!
But when I uncomment the System.out statement to print the interrupt status, it runs into an infinite loop printing "Current thread not interrupted"
I am not able to figure out exactly what difference System.out statement makes.
Note that I don't always get an infinite loop.
I suspect it is due to the interleaving of operations. It helps to also check if the thread is alive:
System.out.println("Current thread not interrupted!!! Alive? " + t.isAlive());
If the thread is not alive, its interrupted status is false.
I get an output like:
Starting thread...Thread-0
Thread is interrupted!!!
Current thread not interrupted!!! Alive? true
Current thread not interrupted!!! Alive? false
[infinite loop]
I guess the first loop sees the thread not interrupted because the InterruptedException has removed the flag - then you reset the flag with interrupt() in the run() method and the thread can finish and is not alive any more.
The next loop check sees it not alive and you start an infinite loop.
An interesting variation can be obtained by adding:
System.out.println("Exiting Thread!!!");
At the end of the run() method - it provides a delay long enough for the loop condition to be checked between the time the interrupted flag is reset and the time the thread dies.
I have a problem with understanding this code. I have only a couple of hours' knowledge of Java.
Here is the code :
// Create a new thread.
class NewThread implements Runnable {
Thread t;
NewThread() {
// Create a new, second thread
t = new Thread(this, "Demo Thread");
System.out.println("Child thread: " + t);
t.start(); // Start the thread
}
// This is the entry point for the second thread.
public void run() {
try {
for(int i = 5; i > 0; i--) {
System.out.println("Child Thread: " + i);
// Let the thread sleep for a while.
Thread.sleep(50);
}
} catch (InterruptedException e) {
System.out.println("Child interrupted.");
}
System.out.println("Exiting child thread.");
}
}
public class ThreadDemo {
public static void main(String args[]) {
new NewThread(); // create a new thread
try {
for(int i = 5; i > 0; i--) {
System.out.println("Main Thread: " + i);
Thread.sleep(100);
}
} catch (InterruptedException e) {
System.out.println("Main thread interrupted.");
}
System.out.println("Main thread exiting.");
}
}
And here is output of it :
Child thread: Thread[Demo Thread,5,main]
Main Thread: 5
Child Thread: 5
Child Thread: 4
Main Thread: 4
Child Thread: 3
Child Thread: 2
Main Thread: 3
Child Thread: 1
Exiting child thread.
Main Thread: 2
Main Thread: 1
Main thread exiting.
Here are my questions.
I want to understand the pattern the code follows. According to me,
First of all, the Program should start to execute the main() function. So, instance of NewThread should be initialized.
Then, I have to go into NewThread constructor and write Child thread: Thread[Demo Thread,5,main]
After that t.start() comes and therefore Program should execute public void run() (AM I WRONG HERE ?? )
In public void run(), I think I should have gotten an output Child Thread 5, but instead I got Main Thread 5. I wonder why ??
Is there anyone to help me ?? Thanks in advance.
t.start() creates a new thread, and calls run() from that. At that point, there are two threads running independently: the one that called start(), and the new one. The original thread returns from the constructor and then starts executing the loop in the main() method.
As the two threads are independent, there's no guarantee which thread will reach a call to System.out.println first. In the sample output that you've given, it so happens that the original thread gets to print first. It could easily happen the other way round though.
As an aside, if you're new to Java I would suggest you learn the basics of the language before you get to threading. There's nothing in your question which indicates that you're confused, but threading is a relatively advanced topic, and it's worth being comfortable with the general language behaviour before you get that far, IMO. That way you can be confident that any odd behaviour you see really is due to threading and not to misunderstanding other parts of the language.