Adding delay in between 2 threads running one after another [closed] - java

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.

Related

Thread control in Java [closed]

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?

Why does this empty synchronized block affect the output of the program? [closed]

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 4 years ago.
Improve this question
So I was just messing around with basic concurrency when I noticed the empty synchronized block shown in the program causes the outputs to sync up. There is nothing in the block, so why does it do this?
public class MainClass {
public static void main(String[] args) throws InterruptedException {
SyncTest f = new SyncTest();
f.start();
for (int i = 0; i < 20; i++) {
System.out.println("MAIN THREAD:" + i);
Thread.sleep(500);
synchronized (f) {
for (int t = 0; t < 15; t++) {
Thread.sleep(100);
}
}
}
}
}
class SyncTest extends Thread {
#Override
public void run() {
for (int i = 0; i < 10; i++) {
try {
System.out.println("OTHER THREAD: " + i);
Thread.sleep(1300);
synchronized (this) {} //Why does this have an effect on the output when commented?
} catch (InterruptedException ex) {}
}
}
}
The mechanics of the synchronized can be summed up like this
synchronized(f) { //wait for no-one use f
// do some stuff
//nobdy can use f during this time
} //free f, other can use it
It basically act like if you used a lock, where the lock is f
So even if your block does nothing than waiting, during this wait time f is not available. So it will synchronize your program even if there's only a wait in your block
The execution flow will not enter a synchronized block if the specified lock has already been taken by another thread. This is always the case, even if the synchronized block contains no code at all.
The locks in your example are the same object (the instance of SyncTest.) So while the non-empty synchronized block is running, the empty one will be waiting for it to complete. In this case, because of the way the Thread.sleep() calls line up, it just so happens that the outputs are reasonably likely to be synchronized as a result.
You've got synchronized 2 times by the same object.
First time in the MainClass:
SyncTest f = new SyncTest();
synchronized (f) {...}
Second time in the SyncTest instance itself by "this":
synchronized (this) {}
There are 2 threads in your program: main thread and thread of SyncTest.
Each thread comes to the point of synchronization by SyncTest object and waits until another thread will go out of the synchronization section.
Berry's answer summarizes what synchronized does and mentions that the content of the block does not matter. So the question is not really why the behavior changes, but why it changes so drasticly.
Your threads "sync up" (i.e. log one by one even though otherThread should be a bit faster and sometimes log twice before mainThread) because your mainThread sleeps for a solid 1500ms when blocking the sync object:
synchronized (f)
{
for (int t = 0; t < 15; t++) // this is
{ // (roughly)
Thread.sleep(100); // equivalent to
} // Thread.sleep(1500);
}
That means that mainThread doesn't give otherThread a chance use its speed advantage (1300 ms vs. 1500ms) and makes it wait until it is done sleeping. Change that piece of code to
for (int t = 0; t < 15; t++)
{
synchronized (f)
{
Thread.sleep(100);
}
}
and otherThread will slide right into one of those breaks between the 100ms naps and the empty sync block is not affecting anything much anymore.
Note that the empty sync block still has a little effect and might change the order of the logs a bit because otherThread might still have to wait a little (but only a maximum 100ms instead of 1500ms). It won't result in such a strict back-and-fourth anymore, though.

How to make a timer using Thread.sleep() while waiting for console input?

I'm trying to write a program that asks simple questions with a time limit on them.
So far I have the following:
public static void main(String[]args) throws IOException, InterruptedException{
Thread thread = new Thread();
Scanner scan = new Scanner(System.in);
System.out.println("1. What is 1+1?");
System.out.println("a. 2\tb. Cannot Be.\tc. 3\td. All of the above.");
String question1 = scan.next();
for(int i = 3; i>=0; i--){
System.out.print("\b"+i);
Thread.sleep(1000);
}
}
This properly asks the question and takes the answer, but it doesn't put a time limit on input and counts down from 3 to 0 after the input is given. What am I doing wrong?
This can be done using a little bit of black multithreading magic.
First, you'll need two threads like this:
Thread thread1 = Thread.currentThread();
Thread thread2 = new Thread(() -> {
try {
for (int seconds = 3; seconds > 0; seconds--) {
System.out.println(seconds+" second"+(seconds == 1 ? "s" : "")+" left");
Thread.sleep(1000);
}
System.out.println("Time's up!");
thread1.stop();
}catch(InterruptedException weCanIgnoreThisException){}
});
where thread1 is the thread that asks the question and thread2 is the countdown.
Then what is left is to ask the question. Don't forget to start() thread2 before asking for input and to stop() it after receiving the input!
System.out.println("1. What is 1+1?");
System.out.println("a. 2\tb. Cannot Be.\tc. 3\td. All of the above.");
thread2.start();
String answer = scan.next();
thread2.stop();
Alright, so here's why I used the deprecated method Thread#stop().
The official documentation of java.lang.Thread explains why is stop() deprecated and what circumstances make it screw up programs:
Stopping a thread with Thread.stop causes it to unlock all of the monitors that it has locked (as a natural consequence of the unchecked ThreadDeath exception propagating up the stack). If any of the objects previously protected by these monitors were in an inconsistent state, the damaged objects become visible to other threads, potentially resulting in arbitrary behavior.
In short, if a thread is stop()ped while it's locked on an object using a synchronized block or method, the lock on the object is released in a dangerously abrupt manner. Since asking multiple choice questions and placing a time limit on input doesn't require a thread to be synchronized on something, we can ignore this.
I would create separate functions to call during the loop, so you don't have a long winded declaration of global variables and such. If you need to control what is called randomly, then you can put a rand in a function and use one global that way, or you can simply put them in a order you want it to be called and completed as.
As you rightly guessed, you need two separate threads running like in the below explanation & code.
The below explanation will provide you more details on what and how you need to do with the two threads.
(1) Thread 1: Timer thread (Inner class implements Runnable) runs in a separate thread and counts the seconds while waiting for the user's input. Once user enters the input this thread needs to be stopped using a signal (stopTimer variable acts as a signal), ensure that stopTimer variable is volatile (to receive the data written by Thread2), otherwise this thread will wait infinitely.
(2) Thread 2: This is the main thread which waits for the user's input. Once the user inputs the data, this main thread signals to stop the Timer thread using a separate method call - signalStopTimer()
public class TimerTest {
public static class Timer implements Runnable {
private volatile boolean stopTimer = false;
private long timerMilliSeconds =0;
#Override
public void run() {
try {
while(!stopTimer) {
Thread.sleep(1000);
timerMilliSeconds = timerMilliSeconds+1000;
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public void signalStopTimer() {
stopTimer = true;
}
//this method will be helpful to find the elapsed time in seconds
public long getTotalTimeInSeconds() {
return timerMilliSeconds/1000;
}
}
public static void main(String[] args) {
TimerTest.Timer timer = new TimerTest.Timer();
//Start the Timer Thread now
Thread thread = new Thread(timer);
thread.start();
Scanner scan = new Scanner(System.in);
System.out.println("1. What is 1+1?");
System.out.println("a. 2\tb. Cannot Be.\tc. 3\td. All of the above.");
String input = scan.next();
//received the input, signal to stop timer
timer.signalStopTimer();
System.out.println(" input is:"+input+" seconds");
System.out.println(" total time :"+timer.getTotalTimeInSeconds());
}
}
In case you only need to count the time it took until user put his input, the better way and the easiest way is to use System.currentTimeMillis().
before the scan code you can save the current time in a variable (Long), then in while loop (when the loop condition will be stopped when the user put his input) in the end of the loop just save the same way mentioned above the current time in millisecond and then all left is subtraction.
if this is your direction let me know i can supply a code for that ;)

How do I interrupt the thread and ask it to complete its work when exit has been pressed by user?

The following snippet is a thread named "Foo" that sleeps for 1 minute and then copies the data typed in 1 minute to a log file.
while(isStarted) {
try {
Thread.sleep(60000); // sleep for 1 minute
ArrayList<String> keyStrokeList = nativeMethods.getKeyStrokeList();
int result = copy.copyToLogFile(keyStrokeList);
System.out.println(result);
} catch(Exception exc) {
exc.printStackTrace();
}
}
I will describe one situation :
Foo thread has finished copying all the data typed in last one minute and it has been 30 seconds since it is asleep. This thread unaware of the situation that several keys are being tapped when it is asleep,will never be able to copy the key strokes into the log file when one presses System.exit(0).
Is there any way I can interrupt this thread i.e awake it and ask it to copy the data to the log file.
Please discuss how should I approach this problem.
The situation in the question :
loop started
thread is sleeping and will sleep for 1 minute
after a minute,it gets the keys tapped in the last 1 minute and copies all that
to a file
Thread sleeps again..and will sleep for 1 minute before it copies the keystrokes
It has been about 30 seconds and thread will sleep for 30 seconds more before it starts
copying the key strokes
suddenly the user presses exit button in the application
The user wants that key strokes be recorded till the second he presses exit
I cannot do System.exit(0) before checking the thread is asleep or not
How do I do this. Should I awake it or make a different call to the list and get the
key strokes because they are being recorded ? And how shall I awake it ?
You're part way there...
while(isStarted) {
try {
Thread.sleep(60000); // sleep for 1 minute
} catch(InterruptedException exc) {
exc.printStackTrace();
}
ArrayList<String> keyStrokeList = nativeMethods.getKeyStrokeList();
int result = copy.copyToLogFile(keyStrokeList);
System.out.println(result);
}
What you need to is provide a way to terminate the loop...
public void dispose() {
isStarted = false;
interrupt();
try {
join();
} catch(InterruptedException exc) {
exc.printStackTrace();
}
}
You should also know that the JVM will not exit until all non-daemon threads have completed (under normal shutdown). This means you can call System.exit(0) and the JVM will not terminate until the logger thread has terminated.
You could use this, but attaching a shut down hook which would have the capacity to call the dispose method on the logger thread...just a thought
You should use a shared object between 2 thread to implement wait/notify pattern instead of Thread.sleep(..) method.
In your condition, there are 2 threads:
Which reads buffer at 1 min interval. (Thread1)
Which will receive "exit" event first. (Thread2)
So, whenever you create instance of Thread1 you can pass a Java Object (new Object()) to it. Reader thread can be put into sleep using object.wait(60*1000); So it will sleep for max 1 minute if object.notify() is not called in 1 minute. If object.notify() is called in this duration, thread will immediately resume.
So, whenever user wants to exit from application you can call object.notify(); which will resume reader thread.
If I failed to explain you the solution due to my bad English please let me know. I will provide you a code sample.
Here's a fairly simple test case to show a way to do this:
public class InterruptTest
{
#Test
public void test() throws InterruptedException
{
//Create the logging thread and start it
LogRunnable runnable = new LogRunnable();
Thread t = new Thread(runnable);
t.start();
//Wait some time
Thread.sleep(3500);
System.out.println("User has pressed exit, starting shutdown");
//Tell the runnable to shut down
runnable.halt();
//Interrupt the thread to wake it up
t.interrupt();
//Wait until thread terminates
t.join();
System.out.println("Exiting");
}
private static class LogRunnable implements Runnable
{
private static final int SLEEPMS = 2000;
private boolean isStarted = true;
private int runCount = 1;
public void halt()
{
this.isStarted = false;
}
public void run()
{
while(isStarted)
{
try
{
Thread.sleep(SLEEPMS);
}
catch(InterruptedException e)
{
System.out.println("Interrupted");
}
catch(Exception exc)
{
exc.printStackTrace();
}
//Do work
System.out.println("Work done " + runCount++);
}
}
}
}
Output:
Work done 1
User has pressed exit, starting shutdown
Interrupted
Work done 2
Exiting
When the user presses the exit key, you signal your main thread to start shutting everything down (in the test-case, it simply waits for some time)
The logging thread is told to halt and awakened via a interrupt() -call
Before exiting, the main thread calls join() to wait until the logging thread has completed, you could consider using an overload that takes a timeout in case something goes wrong
The logging thread wakes up with InterruptedException, completes the code after the catches and terminates
After the logging thread has terminated, the main-thread returns from the join()-call and terminates

Program not waiting for Timer to finish before continuing its loop

I have the following code that runs whenever you click the Start button on my program. I have denoted via comments where I want the timer to go, problem is, when I do thread.sleep(time) it freezes my program! So, I was wondering if someoen could just simply add atimer to my code so it runs the first bit, waits, then runs it again based on bumpNum.
Code:
public class startReplyButtonListener implements ActionListener{
public void actionPerformed(ActionEvent ev){
int length = textAreaReplyMessage.getText().length();
int remLen = 400 - length;
String strHTML = neo.get("http://www.neopets.com/neoboards/topic.phtml?topic=" + txtTopicID.getText());
/*strHTML = neo.post("/neoboards/process_topic.phtml?", new String[][] {{"boardType", "topic_id", "board_id", "message", "next", "remLen"}, {"reply", txtTopicID.getText(), "4", textAreaReplyMessage.getText() , "1", ((Integer)remLen).toString()}});
if(strHTML.contains("No topic with ID")){
txtLog.append("Invalid Topic ID! \n");
}
else{
txtLog.append("Bumped Topic ID " + txtTopicID.getText() + "\n");
}
*/
System.out.println(strHTML);
bumpNum = 5;
wait = Integer.parseInt(textWait1.getText()) * 1000; //converting to miliseconds
int i=1;
do{
strHTML = neo.post("/neoboards/process_topic.phtml?", new String[][] {{"boardType", "topic_id", "board_id", "message", "next", "remLen"}, {"reply", txtTopicID.getText(), "4", textAreaReplyMessage.getText() , "1", ((Integer)remLen).toString()}});
txtLog.append("Board Bumped. Waiting "+ ((Integer)(wait/1000)).toString() +" Seconds..." + "\n");
//ADD TIMER HERE
i++;
}while(i <= bumpNum);
}
}
What I wish to accomplish:
User indicates how many times they want to "post"(indicated by bumpNum), the loop will first, post once:
strHTML = neo.post("/neoboards/process_topic.phtml?", new String[][] {{"boardType", "topic_id", "board_id", "message", "next", "remLen"}, {"reply", txtTopicID.getText(), "4", textAreaReplyMessage.getText() , "1", ((Integer)remLen).toString()}});
Then:
Based on users input, it will wait for however many seconds(txtWait1) and THEN repeat the posting code above until it has reached bumpNum.
And it will update txtLog with the following EACH TIME it bumps(so the program cannot be frozen):
txtLog.append("Board Bumped. Waiting "+ ((Integer)(wait/1000)).toString() +" Seconds..." + "\n");
Edit:
Sigh. Ok, now I understand. I don't know the answer. You are talking about drawing a GUI element. I suspect you want to fork a thread to do a job and then show the GUI display that you are waiting for it. You need to wait for the thread to finish (see my join code below) all of the time having the GUI element refresh UNTIL it finishes when you display some result.
This depends more on the GUI code than sleep/timer. I would start a new question now and explain !!!NOT WITH CODE!!! but with pseudo code from 1000 foot view what you want. Something like:
I am trying to fork a thread that runs in the background in [Swing/Android/etc]. I want to display to the user that the thread has been forked, I want the user interface to wait for the thread without freezing, and then I want the user interface to join with the thread and display the results.
Think about the problem like we have to think of it. Anticipate questions that we will ask. Figure out what we don't and can't know about your environment.
Best of luck.
Edit:
If you are just trying to call sleep then you don't need to fork a thread for that. All you need to do in your code is:
try {
Thread.sleep(waitingTime);
System.out.println(waitingTime);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
e.printStackTrace();
}
This will pause the current thread (which could be the main thread) for waitingTime milliseconds.
So you are forking 3 threads very quickly which I guess you don't want to do. If you are trying to wait for each thread to finish then you will have to do something like:
Thread thread = new Thread(new Counter(wait));
thread.start();
thread.join();
Couple of other comments:
It is considered bad form to start a thread in the constructor of a class: new Thread(this).start();
You are creating 2 thread objects inside of your Runnable. You should just create one outside of your Runnable. See above.
Thread myCounter = new Thread(this); << #1
public Counter(int waitingTime) {
new Thread(this).start(); << #2
}
I would not initialize waitingTime = 0; when defined and initialize it in the constructor. This is confusing. Remove the = 0.
    int waitingTime; << remove the =0 here
    public Counter(int waitingTime) {
 this.waitingTime = waitingTime;
When you catch InterruptedException, be sure to handle it right. A good pattern is to reset the interrupt flag and/or quit the thread:
} catch (InterruptedException e) {
// resets the interrupt flag cleared by catching the exception
Thread.currentThread.interrupt();
// or stops the thread immediately
return;
}
You're starting a new thread each time through the loop. Rather than creating a new thread in the constructor, move the do/while loop into a normal method rather than the run method of a new thread. What you're doing is spawning a new thread that does in fact sleep, but it's not the thread that's executing the loop so that thread just continues as normal.

Categories

Resources