This question already has answers here:
How Thread.sleep() works internally
(5 answers)
Closed 3 years ago.
It may be a dumb question but i have researched it alot and i am not getting any satisfactory knowledge.
Can anyone help me to understand?
my code
public class sleepclass extends Thread {
public static void main(String[] args) {
sleepclass t1 = new sleepclass();
sleepclass t2 = new sleepclass();
t1.start();
t2.start();
}
public void run() {
for (int i = 1; i < 5; i++) {
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
System.out.println(e);
}
System.out.println(i);
}
}
}
Output :
1
1
2
2
3
3
4
4
Now as per the output i can see both thread gone to a sleep state. and both comes after at the same time
My question is :
1 . Since sleep is a static method how both works and sleep at same time? (explain in layman please).
Can i sleep only t1 and left t2 to run?
Thread.sleep() sleeps the current thread. It has no effect elsewhere.
If you want one thread to sleep and one not in your current code, you would have to have some kind of indicator to control it. Such as a boolean flag which you would then check:
if(shouldSleep) {
Thread.sleep(5000);
}
Otherwise all threads will execute the same code, and all threads will sleep for 5 seconds.
Related
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed last month.
Improve this question
The main thread calls a method which asks for user input and sets the appropriate ActionListener (using Swing). The main thread needs to know the user's input before it can continue meaningfully. Under normal circumstances, the main thread will continue and complete itself before the ActionListener is activated. I have been able to work around this by pushing the main thread into a timer, which checks for input from the user and reacts only after that input has arrived. This is inconvenient, because the continuation of the main thread's logic has to occur within the timer block. It seems clumsy, and does not help the readability of the program.
My question : Surely there is a more elegant way of achieving the same result?
Ideally, I suppose, I would want a type of conditional suspension of the main thread.
I received 4 very useful answers to my question - many thanks to the people who suggested answers. After receiving those 4 answers, my question was closed, for the reason given : "Provide more detail and clarity".
So now I will provide code, detail and clarity, at least for part of the problem.
I made a thorough investigation into the suggestion made by Pavel : "so you need to wait for the other thread to finish its job? have you explored thread.join() functionality? It will be helpful if you could share some of your code."
I found the following code on javatpoint.com, which illustrates the functionality of the thread.join method.
package packThreads;
public class JoinExample1 extends Thread
{
public void run()
{
for(int i=1; i<=4; i++)
{
try
{
Thread.sleep(500);
}catch(Exception e){System.out.println(e);}
System.out.println(i);
}
}
public static void main(String args[])
{
// creating three threads
JoinExample1 t1 = new JoinExample1();
JoinExample1 t2 = new JoinExample1();
JoinExample1 t3 = new JoinExample1();
// thread t1 starts
t1.start();
// starts second thread when first thread t1 is dead.
try
{
t1.join();
}catch(Exception e){System.out.println(e);}
// start t2 and t3 thread
t2.start();
t3.start();
}
}
The following output is produced, showing how the join method achieved the desired result :
1
2
3
4
1
1
2
2
3
3
4
4
Next, I modified the code to apply it to my particular problem. Here is the modified "Main" class :
package packThreads;
public class MainJoin {
public static void main(String[] args) {
// creating three threads
SpecialThread t1 = new SpecialThread();
JoinExample1 t2 = new JoinExample1();
JoinExample1 t3 = new JoinExample1();
// thread t1 starts
t1.start();
// starts second thread when first thread t1 is dead.
try
{
t1.join();
}catch(Exception e){System.out.println(e);}
// start t2 and t3 thread
t2.start();
t3.start();
}
}
And the new "SpecialThread" class :
package packThreads;
public class SpecialThread extends Thread {
public void run()
{
for(int i=1; i<=4; i++)
{
try
{
Thread.sleep(500);
}catch(Exception e){System.out.println(e);}
System.out.println(i);
}
System.out.println("Now the special thread will");
System.out.println(" start doing special things");
UserInputFrame inputFrame1 = new UserInputFrame();
}
}
And finally, the "UserInputFrame" class :
package packThreads;
import javax.swing.*;
import java.awt.event.*;
public class UserInputFrame extends JFrame implements ActionListener {
JButton b;
UserInputFrame()
{
System.out.println("Setting up the click button");
b=new JButton("Click");
b.setBounds(100,150,80,30);
b.addActionListener(this);
this.add(b);
setSize(300,300);
setLocation(800,300);
setLayout(null);
setVisible(true);
}
public void actionPerformed(ActionEvent e){
b.setText("Clicked");
System.out.println("Button has been clicked");
this.dispose();
}
}
This modified code produces the output :
1
2
3
4
Now the special thread will
start doing special things
Setting up the click button
1
1
2
2
3
3
4
4
Button has been clicked
The output shows that the thread.join method has not solved my problem. Thread 1 (which asks for the input) terminates itself (despite the "join" coding) before the user has clicked the button. I'm guessing that when calling the UserInputFrame method, a new thread is created, which runs independently of its parent thread (Thread1).
I will now show the clumsy way I have worked around the problem, using a timer.
Changes have been made to the "SpecialThread" class :
package packThreads;
import java.util.Timer;
import java.util.TimerTask;
public class SpecialThread extends Thread {
public void run()
{
for(int i=1; i<=4; i++)
{
try
{
Thread.sleep(500);
}catch(Exception e){System.out.println(e);}
System.out.println(i);
}
System.out.println("Now the special thread will");
System.out.println(" start doing special things");
UserInputFrame inputFrame1 = new UserInputFrame();
new Timer().schedule ( new TimerTask()
{
public void run()
{
if (inputFrame1.b.getText().equals("Clicked"))
{
System.out.println("I have the user input");
System.out.println("and can continue with the logic,");
System.out.println("but I'm stuck within the timer block.");
this.cancel();
}
else { } // do nothing
}
}, 100,100);// start time -- run every x time in milliseconds
System.out.println("Thread1 is now completing.");
}
}
Here is the output produced :
1
2
3
4
Now the special thread will
start doing special things
Setting up the click button
Thread1 is now completing.
1
1
2
2
3
3
4
4
Button has been clicked
I have the user input
and can continue with the logic,
but I'm stuck within the timer block.
So, I'm back to my original question : Surely there's a more elegant way to do this?
This question already has answers here:
How can I measure thread waiting time?
(3 answers)
Closed 3 years ago.
If I use wait() function to put a thread in wait for 20 seconds, then I notify this thread with another thread before it finishes waiting. Can I possibly get the actual waiting time?
One way of achieving this would be starting a stopwatch before the wait and see how long it took until the thread proceed:
Object ob;
public void waitingThread(){
try {
Long before =System.nanoTime();
ob.wait(20);
long waitTime = System.nanoTime() - before;
} catch (InterruptedException e) {
e.printStackTrace();
}
}
Sorry for the wait without the loop
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 3 years ago.
Improve this question
I"M TRYING TO PUT A 5 SECONDS GAP BETWEEN 2 THREADS,THAT RUNS ONE AFTER ANOTHER I.E. SUPPOSE MY 1ST THREAD PRINTS "X" ,THERE WILL BE 5 SECONDS DELAY & THEN ANOTHER THREAD IS PRINTED "Y", AGAIN 5 SECONDS DELAY & THEN "X" & THIS IS GOES ON , SAY 30 TIMES.
import java.lang.*;
import java.util.concurrent.TimeUnit;
class PingPong implements Runnable
{ String word;
PingPong(String s){
word = s;
}
public void run()
{
try
{
for(int i = 0; i<30; i++)
{
System.out.println(word);
Thread.sleep(100) ;
}
} catch (InterruptedException e)
{ e.printStackTrace(); }
}
public static void main(String[] args){
Runnable p1 = new PingPong("ping");
Thread t1 = new Thread(p1);
t1.start();
Runnable p2 = new PingPong("pong");
Thread t2 = new Thread(p2);
t2.start();
}
}
Threads are independent of each other unless you introduce some kind of synchronisation mechanism. So the first thing you need to do is change your PingPong class to take something to synchronize on, on which each thread is going to wait.
Let's call this object ball. You can pass it in the constructor of PingPong. It can be any object you want (even just Object) or you can create your own small class for it.
Then in your loop, you can do:
synchronized(ball) {
System.out.println(word);
Thread.sleep(5000);
}
Thread.sleep(1000);
This way each thread will block for 5seconds until it allows another thread to 'take' the ball's monitor and output it's word.
The second sleep is arbitrary but important so that the same thread doesn't get the monitor again.
A slightly more complex but more correct way to do it is to use a second ReentrantLock. Again you have to pass it through the constructor together with the previous ball object. Let's call this lock.
lock.lock();
synchronized(ball) {
try {
System.out.println(word);
} finally {
lock.unlock();
}
Thread.sleep(5000);
}
The unlock() is in a finally block to ensure that if any exception is thrown the lock doesn't remain locked forever.
The System.out didn't actually need to be inside the try block, but this makes the code a bit more elegant, rather than having an empty try. The sleep() has to be outside, to make sure the other thread goes in through the first lock while this thread is sleeping.
This ensures that if thread Ping is sleeping, thread Pong takes the lock, so it will be next to go inside the synchronized block. When Ping wakes up and goes out of the synchronized block, even if coincidentally gets scheduled before Pong, it won't be able to proceed because it can't take the lock, and has to wait for Pong to go inside the synchronized block and output its word.
This question already has answers here:
Why is i++ not atomic?
(10 answers)
What is a debugger and how can it help me diagnose problems?
(2 answers)
Closed 4 years ago.
I wanted to test out multithreading for a project of mine, trying to also develop a solution in case something goes wrong.
So I made this small test:
main
public class main
{
static int addToCounter;
static int addToErrorCounter;
public static void main(String[] args) throws InterruptedException
{
int threads = 10;
Executor exec = new Executor();
for (int i = 0; i < threads; i++)
{
double error = Math.random();
testClass aldo = new testClass();
Thread thread = aldo.getThread(300, error);
exec.execute(thread);
}
while (threads != (addToCounter + addToErrorCounter))
{
System.out.println("Not all threads finished, number of finished threads is: " + (addToCounter + addToErrorCounter));
Thread.sleep(50);
}
System.out.println("Number of Threads that finished correctly: " + addToCounter);
}
}
testClass
import test1.main;
public class testClass
{
public Thread getThread(long time, double error)
{
Thread thread = new Thread()
{
public void run()
{
try
{
Thread.sleep(time);
}
catch (InterruptedException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
if (error > 0.5)
{
main.addToErrorCounter++;
throw new java.lang.Error("HELLO");
}
System.out.println("I DID THIS!");
main.addToCounter++;
}
};
return thread;
}
}
(you'll have to fix the imports, also I use a custom class Executor, although that's only a wrapper for ExecutorService)
The weird behaviour is that sometimes it works properly, and sometimes it doesn't (total terminated thread count is 9, although I can see clearly it printed "I DID THIS!" and the error exactly 10 times).
Any fix?
The Problem might be a racecondition.
the "++" operator is not atomic.
Imageine the following scenario. There are two Threads at the same time. both want to increase a number and finish.
The initial value of the number is 0.
Thread 0 reads the number, knows now it is 0.
Thread 1 reads the number, knows now it is 0.
Thread 0 (who knew it was 0) now writes 1 to the memory.
Thread 1 does not know, that the number has changed, and still believes the number is 0 so he also writes a 1 to the memory.
You need something like a synchronizing mechanisim, something like a lock, or a semaphore or something else.
have a look at this for more information: http://winterbe.com/posts/2015/04/30/java8-concurrency-tutorial-synchronized-locks-examples/
for your example you could use the "synchronized" example from that link.
add a method to your main class looking like this to increment the addToCounter and also to the addToErrorCounterto remove the effects from your error counter:
synchronized AddToError(int e){
addToError += e;
}
synchronized IncCounter(){
addToCounter++;
}
call those methods in your threads in the testclass instead of incrementing them unsynchronized.
My guess is that the postfix operator (main.addToCounter++) is not atomic. This line of code is probably equivalent to something like:
int temp = main.addToCounter;
main.addToCounter = temp + 1;
return temp;
With multiple threads doin this at the same time, two threads could obtain the same value for temp (because both peform the first line in the above pseudo-code before either performs the second), and hence the counter total will be too small once all threads are complete. See Why is i++ not atomic? for more information.
A quick fix in this situation is to make addToCounter an AtomicInteger, then use addToCounter.incrementAndGet() in place of addToCounter++.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I have the following code:
class Hi
{
public static void main (String [] args)
{
int a = 1;
for (int i = 0; i < 50; i++) {
a = a + i;
System.out.println ("a before sleep is " + a);
try {
Thread.sleep(4000);
} catch (InterruptedException e) {
}
System.out.println ("a after sleep is " + a);
}
}
}
I open two console windows and do java Hi in first one. Then wait for about 10 seconds seconds and do the same in the second window. Both outputs are the same:
a before sleep is 1
a after sleep is 1
a before sleep is 2
a after sleep is 2
a before sleep is 4
a after sleep is 4
a before sleep is 7
a after sleep is 7
a before sleep is 11
a after sleep is 11
with no interleaving. So what's the stir about concurrency issues if I even didn't bother to use synchronized statement? Is it because the code run from different console windows is executed on different processor cores? If so, I've carried out this experiment about 20 times and the results are still the same.
I open two console windows and do java Hi in first one. Then wait for about 10 seconds seconds and do the same in the second window.
You're starting two entirely separate process. That's not using multithreading at all - each process will have its own variables, its own output, everything.
To see multithreading, you need to create threads in a single process. For example:
import java.util.Random;
class Counter implements Runnable {
private int a;
public void run() {
Random random = new Random();
for (int i = 0; i < 10; i++) {
String name = Thread.currentThread().getName();
a++;
System.out.println(name + " Before sleep, a = " + a);
try {
// Add a little more uncertainty...
Thread.sleep(random.nextInt(1000));
} catch (InterruptedException e) {
// Ignored
}
System.out.println(name + " After sleep, a = " + a);
}
}
}
public class ThreadingTest {
public static void main(String[] args) throws InterruptedException {
Counter counter = new Counter();
Thread t1 = new Thread(counter);
Thread t2 = new Thread(counter);
t1.start();
t2.start();
}
}
You have two different JVM's so two main threads running on two different JVM's so concurrency dont apply.
Yes if you have two threads within same JVM then concurrency applies.
These are two separate processes on your computer. They do not share data or anything else. They are no more related then, for example, your web browser and your wordprocessor. They each have their own separate "a" variable, each completely unrelated to the other.
Concurrency issues arise when multiple threads in the same process space try to access the same variable. That does not apply here.
As here you are running two different processes, no matter how many times you run this code you will get same result. As both of these programs will be running within two separate processes.
To run these programs in multi threaded way you have to implement two threads and start them.