Java: Thread doesn't work - java

I'm trying to start a thread in a for-loop. This task should only wait for a second (Thread.sleep()), so every time the loop starts over again, a new thread is started and it should cause the code after the thread to wait until it is executed.
public void count()
{
for(int i = 29; i>=0; i--)
{
Thread t1;
t1 = new Thread(new TimerClass());
t1.start();
String s = String.valueOf(i);
jLabel6.setText(s);
System.out.println(s);
}
}
public class TimerClass implements Runnable{
#Override
public void run()
{
try{
Thread.sleep(1000);
System.out.println("Timer");
} catch(InterruptedException e)
{
}
}
}
As you can see, I implemented in both methods System.out.println() to check if they are actually executed. I get this:
29
28
27
26
...//25 - 3
2
1
0
Timer
Timer
Timer
//in all 29 times Timer
So it should be 29, Timer, 28, Timer and so on, but it isn't.
Does anyone know what's wrong with the code?
Thanks a lot.

Your main loop that is starting the thread is likely dominating the CPU, so it finishes doing its entire loop and only then do the threads get a chance to go.
In fact, given that all of your threads sleep for an entire second and you're only looping 29 times, you're guaranteed that your loop will finish (and print all of the numbers) before your threads do. Add a sleep to your main loop if you want the threads to print - remember, the main loop doesn't stop when you start a thread.

You can join a thread to the main thread so first your thread will finished then main thread
public void count()
{
for(int i = 29; i>=0; i--)
{
Thread t1;
t1 = new Thread(new TimerClass());
t1.start();
t1.join();
String s = String.valueOf(i);
jLabel6.setText(s);
System.out.println(s);
}
}
Here is my code for spawning 2 threads or one thread depends on arrayList size but in my case this threads are doing much more complex tasks then just waiting 1 sec
for (int i = 0; i < array.size(); i += 2) {
Thread t1 = null;
Thread t2 = null;
if (i < array.size() - 1 && array.size() > 1) {
t1 = new Thread(array.get(i));
t2 = new Thread(array.get(i + 1));
t1.start();
t2.start();
}
else {
t2 = new Thread(array.get(i));
t2.start();
}
if (t1 != null)
t1.join();
if (t2 != null)
t2.join();
}
In my code I populate arrayList with Objects that Implements Runnable interface.

Even if you sleep the thread for 1ms, your results would be the same. If you can manage the thread to sleep for the time less than it takes to print the results, your result could be as expected. Here is my code where I have put the time of 1 ms but yet the results are the same.
public class MultiThreading implements Runnable
{
public void run()
{
try
{
Thread.sleep(1);
System.out.println("Timer");
}
catch(Exception e)
{
}
}
public static void main(String [] args)
{
for(int i = 29; i>=0; i--)
{
Thread t1;
t1 = new Thread(new MultiThreading());
t1.start();
String s = String.valueOf(i);
System.out.println(s);
}
}
}
If you comment out the Thread.sleep(1) method, then your results are as you expected.

Delay is much enough to let the for loop in count() to finish before is can print 'timer' from thread.

What is happening is that the thread you started starts executing and immediately goes to sleep. In the meantime, your loop just keeps running. As the whole point of threads is that they run asynchronously, I don't really understand why you think your main loop should be waiting for it to finish sleeping. The thread has started running and is now running independently of the main loop.
If you want to wait for the thread you just started to finish (in which case, you might as well use a method), then use one of the synchronisation primitives, i.e. Thread.wait().

What you actually want to do is block your main thread while another thread is running. Please don't use Thread#sleep statements, as these are unreliable in order to "make your application work". What you want to use instead is Thread#join. See dharr his code for an example.
Also, it's better to use Executors and ExecutorServices when creating threads or running async tasks.

Threads are interesting. Think of a virtual thread as a physical thread. There are many threads on the clothes you're wearing, all working at the same time to hold your shirt together. In virtual terms what Thread.start() does is start a thread on a different strand WHILE the following code continues to execute, (i.e. Two Threads work simultaneously like 2 runners run next to each other). Consider putting a break point right after Thread.start(). You'll understand.
For your desired effect, just put a Thread.sleep() in the main loop. This will cause an output of
29
Timer
28
Timer
// etc.
Hope this helped.
Jarod.

Another analogy to the threads in a shirt:
Think of threads as coworkers to your main programm (which is a thread itself). If you start a thread, you hand some work to this coworker. This coworker goes back to his office to work on this task. You also continue to do your task.
This is why the numbers will appear before the first thread/coworker will output anythig. You finished your task (handing out work to other coworkers) before he finished his.
If you want to give out some work and then wait for it to be finished, use t1.join() as suggested by others. But if you do this, it is senseless to create new Threads, because you don't (seem) to want to process something in parallel (with many coworkers) but in a specific order - you can just du it yourself.

Related

What if I join the terminated(dead) thread

Over here I'm trying to join a thread after it has been terminated, the code is working fine, but my question doesn't it should throw some error messageor any info?
public class MultiThreadJoinTest implements Runnable {
public static void main(String[] args) throws InterruptedException {
Thread a = new Thread(new MultiThreadJoinTest());
a.start();
Thread.sleep(5000);
System.out.println("Begin");
System.out.println("End");
a.join();
}
public void run() {
System.out.println("Run");
}
}
If you look at the source code of Thread::join you will notice that it calls Thread::join(timeout) method. And looking at the source code of this method we can see that it checks status of the thread in a loop by calling Thread::isAlive :
...
if (millis == 0 L) {
while (this.isAlive()) {
this.wait(0 L);
}
} else {
while (this.isAlive()) {
long delay = millis - now;
if (delay <= 0 L) {
break;
}
this.wait(delay);
now = System.currentTimeMillis() - base;
}
}
...
so if a Thread, that you call join on, is terminated - join will just return and do nothing.
I'm repeating info that is already in other answers and comments, but let me try and summarize, while adding explanation.
The point of thread.join() is to wait for the thread to terminate. That's what it tells you in the documentation for join:
Waits for this thread to die.
Waiting for a terminated thread to terminate is pretty straightforward (!), and there seems to be no logical reason why waiting for a terminated thread to terminate should be considered an error. You want to know when the thread finishes. It has.
More significantly, if the caller had to ensure that a thread had not terminated before waiting for it to terminate, that would create a timing window that every caller would have to compensate for. The trivial sequence
Thread t = new Thread(…);
t.start();
t.join();
would be prone to failure due to its inherent race hazard. In other words, that would be a bad way to design join.
No, Thread.join() will return instantly if the thread is already dead
Thread will start the execution. will print Run then thread will sleep for 5 seconds and will print Begin following by End
Output on the console:
Run
---- 5 seconds sleep ------
Begin
End

Why does this multithreaded program output 100 instead of the expected 200?

I'm learning multithreading. Can anyone tell why here the output is always 100, even though there are two threads which are doing 100 increments?
public class App {
public static int counter = 0;
public static void process() {
Thread thread1 = new Thread(new Runnable() {
#Override
public void run() {
for (int i = 0; i < 100; ++i) {
++counter;
}
}
});
Thread thread2 = new Thread(new Runnable() {
#Override
public void run() {
for (int i = 0; i < 100; ++i) {
++counter;
}
}
});
thread1.start();
thread2.start();
}
public static void main(String[] args) {
process();
System.out.println(counter);
}
}
The output is 100.
You're only starting the threads, not waiting for them to complete before you print the result. When I run your code, the output is 0, not 100.
You can wait for the threads with
thread1.join();
thread2.join();
(at the end of the process() method). When I add those, I get 200 as output. (Note that Thread.join() throws an InterruptedException, so you have to catch or declare this exception.)
But I'm 'lucky' to get 200 as output, since the actual behaviour is undefined as Stephen C notes. The reason why is one of the main pitfalls of multithreading: your code is not thread safe.
Basically: ++counter is shorthand for
read the value of counter
add 1
write the value of counter
If thread B does step 1 while thread A hasn't finished step 3 yet, it will try to write the same result as thread A, so you'll miss an increment.
One of the ways to solve this is using AtomicInteger, e.g.
public static AtomicInteger counter = new AtomicInteger(0);
...
Thread thread1 = new Thread(new Runnable() {
#Override
public void run() {
for (int i = 0; i < 100; ++i) {
counter.incrementAndGet();
}
}
});
Can anyone tell why here the output is always 100, even though there are two threads which are doing 100 increments?
The reason is that you have two threads writing a shared variable and a third reading, all without any synchronization. According to the Java Memory Model, this means that the actual behavior of your example is unspecified.
In reality, your main thread is (probably) printing the output before the second thread starts. (And apparently on some platforms, it prints it before the first one starts. Or maybe, it is seeing a stale value for counter. It is a bit hard to tell. But this is all within the meaning of unspecified)
Apparently, adding join calls before printing the results appears to fix the problem, but I think that is really by luck1. If you changed 100 to a large enough number, I suspect that you would find that incorrect counter values would be printed once again.
Another answer suggests using volatile. This isn't a solution. While a read operation following a write operation on a volatile is guaranteed to give the latest value written, that value may be a value written by another thread. In fact the counter++ expression is an atomic read followed by an atomic write ... but the sequence is not always atomic. If two or more threads do this simultaneously on the same variable, they are liable to lose increments.
The correct solutions to this are to either using an AtomicInteger, or to perform the counter++ operations inside a synchronized block; e.g.
for (int i = 0; i < 100; ++i) {
synchronized(App.class) {
++counter;
}
}
Then it makes no difference that the two threads may or may not be executed in parallel.
1 - What I think happens is that the first thread finishes before the second thread starts. Starting a new thread takes a significant length of time.
In Your case, There are three threads are going to execute: one main, thread1 and thread2. All these three threads are not synchronised and in this case Poor counter variable behaviour will not be specific and particular.
These kind of Problem called as Race Conditions.
Case1: If i add only one simple print statement before counter print like:
process();
System.out.println("counter value:");
System.out.println(counter);
in this situation scenario will be different. and there are lot more..
So in these type of cases, according to your requirement modification will happen.
If you want to execute one thread at time go for Thread join like:
thread1.join();
thread2.join();
join() is a Thread class method and non static method so it will always apply on thread object so apply join after thread start.
If you want to read about Multi threading in java please follow; https://docs.oracle.com/cd/E19455-01/806-5257/6je9h032e/index.html
You are checking the result before threads are done.
thread1.start();
thread2.start();
try{
thread1.join();
thread2.join();
}
catch(InterruptedException e){}
And make counter variable volatile.

Join() in multithreading

According to join definition, the join thread executes till its execution is complete and is not prempted in the middle (correct me if i am wrong) .But in the following code: the join thread t1 doesnt stop the main thread to take the control in between the execution of t1. why so ?
public class JavaAtomic {
public static void main(String[] args) throws InterruptedException {
ProcessingThread pt = new ProcessingThread();
Thread t1 = new Thread(pt, "t1");
t1.start();
Thread t2 = new Thread(pt, "t2");
t2.start();
t1.join();
t2.join();
System.out.println("Processing count=" + pt.getCount());
}
}
class ProcessingThread implements Runnable {
private int count;
#Override
public void run() {
for (int i = 1; i < 5; i++) {
processSomething(i);
count++;
System.out.println(Thread.currentThread()+"---"+getCount()) ;
}
}
public int getCount() {
return this.count;
}
private void processSomething(int i) {
// processing some job
try {
Thread.sleep(i * 1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
output:
Thread[t1,5,main]---1
Thread[t2,5,main]---2
Thread[t1,5,main]---3
Thread[t2,5,main]---4
Thread[t1,5,main]---5
Thread[t2,5,main]---5
Thread[t2,5,main]---6
Thread[t1,5,main]---7
Processing count=7
Many Thanks
Jayendra
Here's what is happening in your example:
Main thread starts running, instantiates and kicks off t1 and t2
t1 runs a little
t2 runs a little
The main thread joins on t1 and blocks until t1 finishes
t1 and t2 keep doing their thing. We continue to see output from them. Main thread is blocking.
t1 finishes and main thread unblocks
Main thread joins on t2. However, it just so happens that in your particular output example, t2 actually finished before t1, which is entirely possible under the randomness of the thread scheduler. So, the main thread doesn't block on this second join() call because t2 is already done.
The main thread runs to completion and program exits.
ADDITION
The above answer is unchanged. However I noticed a thread safety issue in your code. You have multiple threads incrementing the count variable in the shared ProcessThread instance by using the ++ operator. Please note that ++ is not atomic (see this article), because it really consists of four operations: reading the current value of count, adding 1 to it, writing the new value back to count, and returning the value to the caller. In the gaps between those four operations, the thread scheduler could pre-empt the current thread and slip in another one carrying an outdated value read from count. Try increasing the number of threads and decreasing the time in your sleep() call and you will see the current count number appear inconsistent (same number may appear more than once, lower before higher, etc.) count becomes subject to race conditions between threads. The solution is to either enclose all reads/writes to count in synchronized, or to use a java.util.concurrent.atomic.AtomicInteger.
Join stops the thread that calls join. It has no effect on the thread joined.
when you call t1.join(), it won't have any effect on t1's execution. i.e It can't stop t1. t1.join() will wait for t1 to finish and then go forward in the execution.
When main thread reaches the code t1.join() both t1 and t2 have been started and now main thread will wait for t1 to finish. But we can't predict the behaviour of running of t1 and t2, we can only assure that the last line of main function System.out.println("Processing count=" + pt.getCount()); will execute only after thread t1 and t2 finish execution.

How to stop the main process while the spawned threads finish execution

Here's my code
public class Main {
private static class GetData implements Runnable{
private List list;
private SqlQuery query;
GetData(SqlQuery<String> param){
this.query=param;
}
public void run(){
list = query.execute();
}
}
public static void main(String[] args){
ApplicationContext context = new ClassPathXmlApplicationContext("database.xml");
SqlQuery<String> parameter = (SqlQuery<String>) context.getBean("BEAN_NAME");
System.out.println("hello");
new Thread(new Inner(parameter)).start();
for(each element in list of inner class){
System.out.println(element.id);
}
}
}
Well my question is after i get the query from xml file, it executes but it doesnt print anything? Why?
Also, how do i ensure that after all my threads have finished execution, only then my main program moves ahead in execution, given i make another thread and run it to create another list.
Change
new Thread(new Inner(parameter)).start();
to
Thread t = new Thread(new Inner(parameter));
t.start();
and put t.join(); after your for loop.
EDIT:
For 5 or any number of threads say n
Create an array of threads like this
Thread[] tArray = new Thread[n];
for (int j = 0; j < tArray .length; j++) {
//your code to start the thread goes here
}
Once you have started them all, loop through them again at the end of the main function to join each of them to main thread.
for (int j = 0; j < tarray .length; j++) {
tArray.join()
}
If you are using one Thread and want main program waits its execution completed. You do not need to use Thread mechanism. Instead, you can add a method in main program in substance to Thread.run().
Otherwise if you want to use multiple thread you can use Thread.join method so that all other threads wait at that line until all thread execution are completed.
I also advice you to investifate countdownlatch mechanism. It can give you ready mechanism not to involve in Join/wait operations manually.
Use the join method of the thread you want to wait. Thread.join() javadoc
how it works :
The thread (lets call him A) that join another thread (called B) will stop it execution until the joined thread (B) finish and returns.
EDIT :
In fact, unless your Thread is in Daemon mode, your program won't exit.
The JVM automatically joins all running non daemon thread before exiting
new Thread(runnable).start(); executes the provided runnable asynchronously and continues the execution to the next line, so the loop executes before anything has been added to the list.
So if you want to execute the loop after the thread has finished, you will have to wait for it. The easiest way is to run the Runnable: new Inner(parameter).run();.
Now that defeats the purpose of parallel execution.
Assuming you have more than one runnable, you could use an ExecutorService (instead of using the low-level Thread API, which is more complicated to use and error-prone) to run the various tasks in parallel and collect the results when they are all completed:
ExecutorService executor = Executors.newCachedThreadPool();
executor.submit(runnable1); //first task
executor.submit(runnable2); //second task
executor.shutdown(); //stop accepting new tasks
executor.awaiTermination(Integer.MAX_VALUE, TimeUnit.SECONDS); //wait until both tasks finish
//now you can use the results of your tasks.
Finally, note that if you use threads, you will be sharing the list in your runnable across threads (the worker thread and the main thread) and you will need to use a thread safe structure to make that possible - for example, by using a CopyOnWriteArrayList:
list = new CopyOnWriteArrayList(query.execute());

How to slow a thread down in JAVA

I have this class in which I run a for loop 10 times. This class implements Runnable interface. Now in main() I create 2 threads. Now both will run loop till 10. But I want to check loop count for each thread. If t1 is past 7 then make it sleep 1 second so as to let t2 complete. But how to achieve this? Please see the code. I attempted but looks totally foolish. Just how to check the data of a thread ???
class SimpleJob implements Runnable {
int i;
public void run(){
for(i=0; i<10; i++){
System.out.println(Thread.currentThread().getName()+" Running ");
}
}
public int getCount(){
return i;
}
}
public class Threadings {
public static void main(String [] args){
SimpleJob sj = new SimpleJob();
Thread t1 = new Thread(sj);
Thread t2 = new Thread(sj);
t1.setName("T1");
t2.setName("T2");
t1.start();
try{
if(sj.getCount() > 8){ // I know this looks totally ridiculous, but then how to check variable i being incremented by each thread??
System.out.println("Here");
Thread.sleep(2000);
}
}catch(Exception e){
System.out.println(e);
}
t2.start();
}
}
Please help
You should use some synchronization object, and not rely on slowing down of threads. I strongly suggest you take a look at one of the classes at java.util.concurrent package. You can use for this CountdownLatch - thread 1 will await on it, and thread 2 will perform the countdown and release the lock, and let thread 1 continue (the release should be done at the end of thread 2 code).
I added a synchronized Block, which can be entered by one thread at a time. Both threads call and enter the method parallel. One thread will win the race and take the lock. After the first thread leaves the block it waits 2 seconds. In this time the second thread can iterate over the loop. I think this behaviour is wanted. If the second thread must not wait 2 seconds, too, you can set some boolean flag, that the first thread finished the block and use this flag in an if statement, which prevents the wait time of the second thread.
class SimpleJob implements Runnable {
int i;
public void run(){
synchronized (this) {
for(i=0; i<8; i++){
System.out.println(Thread.currentThread().getName()+" Running ");
}
}
try {
System.out.println("Here");
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
for(i=0; i<2; i++){
System.out.println(Thread.currentThread().getName()+" Running ");
}
}
public int getCount(){
return i;
}
}
public class Threadings {
public static void main(String [] args){
SimpleJob sj = new SimpleJob();
Thread t1 = new Thread(sj);
Thread t2 = new Thread(sj);
t1.setName("T1");
t2.setName("T2");
t1.start();
t2.start();
}
}
If the goal is to run 2 Runnables in parallel (as Threads) and wait for them both to finish, you can, in increasing order of complexity/power:
Use Thread.join (as suggested by #Suraj Chandran but his reply seems to have been deleted)
Use a CountDownLatch (as also suggested by #zaske)
Use ExecutorService.invokeAll()
EDIT ADDED
First, I don't understand what the magic "if you are at 7 then wait for the other" logic is all about. But, to use Thread.join() from your main code, the code would look like
t1.start(); // Thread 1 starts running...
t2.start(); // Thread 2 starts running...
t1.join(); // wait for Thread 1 to finish
t2.join(); // wait for Thread 2 to finish
// from this point on Thread 1 and Thread 2 are completed...

Categories