this is my first post on Stackoverflow and obviously i dont have much knowlege about threads.
Its a console app and the thing is, when the main method starts,also the timer starts and my program executes,it involves getting information from keyboard and it works great.
After timer expires,lets say after 20 sec, it calls run() from RemindTask Class and shows me number of points i gather during that time.
Now after that i want to make option to start or not to start again my app,main method.
The thing is my main will still gather informations from keyboard cause its still executing and not from input from run() method which i want.
If i put System.exit(0), ofcourse i cannot start a new thread after it.
How do i get pass this,is there a way to say in my while loop "Until my timer didnt expired do this"? or something?
static class RemindTask extends TimerTask {
public void run() {
char answer;
System.out.println("Time expired! "+yourResult);
/* System.exit(0);
Thread t = new Thread();
t.start(); */
System.out.println("Do you continue? y/n");
Scanner in = new Scanner(System.in);
answer = in.nextLine().charAt(0);
if(answer=='y'){
System.out.println("Continue program");
String[] args = {};
Main.main(args);
}else
System.out.println("Stoping program");
System.exit(0); //Stops the AWT thread (and everything else)
}
}
static int yourResult;
public static void main(String[] args) {
int seconds=20;
timer = new Timer();
timer.schedule(new RemindTask(), seconds * 1000);
boolean contin = true;
while(contin == true){
//...a bunch of code...
//...Scanner in = new Scanner(System.in);..
//...a bunch of code...
}
Stopping a thread is not a trivial task. The short answer to how to stop a thread is: do not stop a thread from within another thread; instead, ask the thread to stop itself. The reason for this is that a thread has to stop in a safe place. If the thread which is stopped holds a mutex, for example, a deadlock may occur if another thread also requires this mutex.
First, probably it is better that you do not use the main method for polling the keyboard. Just create another thread to do this; this makes it easier to make a new thread doing the same thing later.
Second, what you have to do is pass a reference to the main thread's Thread object to your RemindTask thread. Java offers a method Thread.stop() to stop a thread, but it has been deprecated for the reason I gave above.
Instead, you have to ask the main thread to stop. Java offers a standard way of doing this. You call Thread.interrupt() on the Thread instance of the main thread. Then, in the main thread you regularly call the static method Thread.interrupted(). If it returns true, this means that some other thread has asked the current thread to terminate, and you can cleanly stop by returning from the run() method.
It's hard to get what the problem is without the call to the RemindTask.run() method. In the commented part of your code, inside the main method loop, you have a constructor call that is also inside the RemindTask.run(). Maybe that is part of the problem?
Related
When using while(true) loop in main thread with Thread.sleep() the child threads works fine but if i remove sleep method from while loop the child threads do not work. I mean, thread defines parallelism so it should work ?
public static void main(String[] args) {
Thread th1 = new Thread(new Runnable() {
#Override
public void run() {
for (int i=0; i<50; i++) {
System.out.println("I love java.");
Thread.sleep(500);
}
}
});
th1.start();
th2.start(); // Similarly assume thread 2
// Here's my main thread
while(true) {
System.out.println("I am main thread.");
// If i use Thread.sleep(200) here, works fine but if not the child thread do not
print messages
}
}
I am new to java, so might be the question is bit silly. Answers will be helpful.
No, it works fine on both situations.
when you use Thread.sleep() in main-thread the main thread executes slower, thus you can see the "I love java" message (because t1 executes first)
when you don't use Thread.sleep() the main thread executes faster, so you can't see the "I love java" message. but it is there (on the first or second line of output)
debug the program to see more information. debugging shows the number of threads running currently and many more information
If you want to learn more about concurrency(multithreading) visit the link
https://www.baeldung.com/java-concurrency
I have this code sample
public static class BlinkMe extends Thread {
int counter = 0;
protected boolean stop = true;
public void run() {
while (stop) {
counter++;
if (counter % 2 == 0) {
jLabel4.setVisible(true);
jLabel7.setVisible(true);
jLabel8.setVisible(true);
counter = 0;
} else {
jLabel4.setVisible(false);
jLabel7.setVisible(false);
jLabel8.setVisible(false);
if (jButton4.isEnabled() == false) {
stop = false;
jLabel4.setVisible(true);
jLabel7.setVisible(true);
jLabel8.setVisible(true);
if (jButton2.isEnabled() == false) {
stop = true;
jButton2.setEnabled(false);
}
}
}
}
}
}
I need to stop this Thread when I press my Stop Button...
Here's the code I'm using for the Button's function but it is not working. ***The Thread is not working at ll*
Here is the Button's function
private void jButton4ActionPerformed(java.awt.event.ActionEvent evt) {
BlinkMe b=new BlinkMe();
b.stop(); //here I have even used b.interrupt(); but doesn't stop the
}
There are many, many things wrong in this code.
you're accessing Swing components from a background thread. That's forbidden. Only the event dispatch thread is allowed to access Swing components
You're trying to stop() a thread, although this method is deprecaed and should never, ever be used, as the documentation explains
Instead of stopping the actual thread, you create a new instance of that thread class, and call stop() on that new instance.
You "blink" without any delay between the blink.
Your thread uses a stop variable, but this variable is never modified anywhere. Even if it was, it's not volatile, so you have a big chance of not seeing the modification, and thus not stopping the thread.
Read the Swing tutorial abount concurrency. And use a Swing Timer, which is designed to do that kind of thing, safely.
You are creating a new thread in actionPerformed and trying to stop the same, which was not started so far. Try calling stop in actual thread.
The initial value of your stop is "true". This means that when the thread starts, the run method executes but will not execute the while block because the condition will result to false right away.
First, you need to change your while loop into like this:
while(!stop) { /* the rest of your code */ }
Next, you need to create a method in your BlinkMe thread that would allow other objects in your program that would make it stop. The method would look something like this:
public void stopBlinking() {
stop = true;
}
Calling the above method will stop the infinite loop in the run method.
I don't think you will see a blinking effect when you run your program. It is because the loop executes very fast. I suggest you put a Thread.sleep(1000) somewhere in the loop so that there is time to reflect the blink effect visually.
There are two things that I did not clear, one concerns the new operator, the other, the method Thread.sleep.
// Create a second 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);
Thread.sleep(500);
}
} catch (InterruptedException e) {
System.out.println("Child interrupted.");
}
System.out.println("Exiting child thread.");
}
}
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(1000);
}
} catch (InterruptedException e) {
System.out.println("Main thread interrupted.");
}
System.out.println("Main thread exiting.");
}
I know that the new operator is used to allocate an object
for example: Box refvar=new Box(); call the constructor of Box class
in this case the call is new NewThread();
But I have no reference variable, I don't understand how Java call the constructor without reference variable. Normally I use: Nameofclass reference-variable-name = new NameOfConstructor();.
Another thing I do not understand is: how Java can call Thread.sleep() if there is no object with the name Thread? in this case should be: t.sleep(1000) or not?
Thanks in advance.
You can call a constructor without assigning a reference to it.
In your case, the field Thread t maintains a reference to the thread, so there will be no premature garbage collection.
Thread.sleep() sleeps the current thread; i.e. the thread that is currently executing that bit of code.
It is valid to create an object (new File()) without storing the object (File file = new File()). In that case you create the object and call the constructor but can't do anything with the result. In many cases this doesn't do much (but it could change static data or throw an exception).
In your case the constructor NewThread() actually creates a thread and starts it.
Your second question regarding Thread.sleep() actually calls the static function sleep in the class Thread, which will wait for the given time and then return. So this will actually sleep the current thread, and not another thread that you call it on. Note that even calling it on a thread object (someThread.sleep()) still sleeps the current thread and not someThread. In your example the current thread is the main thread (which is created by the JVM and eventually used to call the main function)
new NewThread();
Creates a new object with no reference in your main, therefore after the creation you are no more able to access this object within main. But the object is created anyway.
Thread.sleep(1000);
Secondly, sleep is a static method, therefore you can call this method directly with the classname, you do not need to instanciate an object of thread first for this.
Thread.sleep(...)
is possible because sleep is a static method which
Causes the currently executing thread to sleep (temporarily cease
execution) for the specified number of milliseconds, subject to the
precision and accuracy of system timers and schedulers.
according to the JavaDoc
1) new ClassName() will create an instance. Even if you can't refer to it later, you can call instance methods on that instance there itself.
2) Thread class has a static method called sleep() and static method doesn't require an instance. They can directly be called using the className.methodName()
Thread#sleep always affects only the current thread. You are not allowed to target other threads in order to put them to sleep. Calling t.sleep() results in the static method being called, which affects the current thread. Calling static methods on an instance is a bad idea, it is likely to mislead people who read the code into thinking the code is putting another thread to sleep.
Your NewThread creates a thread in the constructor. Once you start a thread it will run until it terminates, regardless of if anything else has a reference to it. Each thread is a GC root that prevents garbage collection of anything that it references. Keeping a reference to the thread would allow you to interrupt it or otherwise communicate with it.
The posted code looks like it was created by somebody who had heard that using Runnable was preferred over extending Thread, but who had missed the point about why. Having a Runnable create a thread for itself defeats the purpose of separating Runnables (the tasks that need to be executed) from the means of executing the tasks (the threads). This is not a good way to design any real code for a purpose other than causing confusion.
Generally Thread Created 2-way,
1. extends Thread class
2. implements Runnable interface.
Here, you have choose option-2, e.g. Runnable Interface.
In your code,
you have first Created new Thread(...) with new keyword, which is wrap-in Runnable object inside it.
Answer-2 :
Thread.sleep() method : it's pause current thread's execution, while executing it, current thread move to Wait/Block state from Running State of thread life-cycle.
After completion of N-millisecond (here 500, i.e. 0.5 sec.).
that thread again wake up it and comes to Runnable state.
Let me know, if still any query.
System.out.println("Enter the number of what you would like to do");
System.out.println("1 = Manually enter Options");
System.out.println("2 = Use a text file to pick from pre-existing models");
System.out.println("3 = Exit ");
Scanner sc = new Scanner(System.in);
try {
runType = sc.nextInt();
if(runType > 3) {
throw new badValue(999, "Not the valid input");
}
} catch (NullPointerException e) {
} catch (badValue e) {
e.correctBadValue(runType);
}
switch (runType) {
case 1:
Thread a = new SelectCarOption();
a.run();
case 2:
Thread a2 = new BuildCarModelOptions();
a2.run();
case 3:
System.exit(1);
}
}
}
So basically, I'm trying to run a program where the thread that is running is determined by a variable runType. If runType is one value, a certain thread will run and if it is the other, the other will run. Is my approach the most efficient? Will it turn out to give any errors?
Long story short, no, this is not how you want to do things.
thread1.run() doesn't start a new thread, it just calls the code in run() on the current thread. What you want is thread1.start().
thread1.sleep(5000) will not make thread1 sleep, it will make the main thread sleep. Thread.sleep is a static method that affects the current thread, and the fact that you're using an instance variable to invoke it (rather than the more traditional Thread.sleep(5000)) doesn't change that.
It makes no sense to start thread2 and then immediately join to it. You may as well just invoke its code directly on the main thread. (Which is what you're doing right now, since you're invoking thread2.run() instead of thread2.start().)
I'm not sure what your end goals are, but this sounds like a case for plain old polymorphism. Create a Runnable and assign it to one of two concrete implementations, depending on the input; then just invoke run() on it. Something like:
Runnable selectStrategy = (runType == 2)
? new CarModelOptionsIO()
: new SelectCarOption()
selectStrategy.run()
If you need a result from this action, you could use a Callable<T> (don't let the package name confuse you; there's nothing inherent to concurrency in that interface) or even create your own interface, which lets you give more meaningful names to the methods (call and run are pretty unhelpfully generic).
A programmer had a problem. He thought to himself, "I know, I'll solve it with threads!". has Now problems. two he
A)
you can replace
Thread thread1 = new SelectCarOption();
thread1.start();
thread1.join();
by directly executing whatever run does since the thread that starts the thread just waits.
calling thread | new thread
start() ---->
run()
join() <---
does the same thing as
run()
Now we can simplify your code to:
if (runType == 2) {
doCarModelOptionsIO();
} else {
doSelectCarOption()
}
And you have a much more efficient way.
B)
Don't call the run() method on a thread. Every method called directly is executed in place in your current thread. Thread has the start() method that you call which then calls run() from within that new thread.
Overall, your code is confused. I suggest reading the concurrency tutorials if you haven't already. Review them if you have read them. Maybe do a few yourself, then come back to this problem.
You say:
If runType is one value, a certain thread will run and if it is the other, the other will run.
To do that you need something like this...
if (runType == 2) {
Thread thread1 = new SelectCarOption();
thread1.run();
try {
//join blocks until thread 1 terminates. We don't know that it
//ever will give your code
thread1.join(); //stops thread1 to run different thread
} catch (InterruptedException e1) {
e1.printStackTrace();
}
Thread thread2 = new CarModelOptionsIO();
thread2.run();
try {
//blocks again, until thread 2 is done running.
thread2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
} else {
try {
thread1.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
//start some other thread here since runType is different?
}
There are many mistakes in your class. First you are using the method run() instead of start(). Second, you should start both threads for your sleep() make sense. That a look on the Oracle Java Se tutorial online to see the basics of Java Multithreading model, that will help a lot.
There are several mistakes in your code. and to let you know, the code you have written does not spawn a new thread at all. Few thing to note:
Thread.sleep() is a static method. The below code is misleading:
try {
thread1.sleep(5000); //stops thread1 to run different thread
} catch (InterruptedException e1) {
e1.printStackTrace();
}
You have started thread1 in the main thread and then called sleep method using the newly created thread. But this is not gonna help you. It makes the main thread sleep not thread1. To make thread1 sleep you need to call sleep method within the run() of this thread1 class.
Moreover, sleep() is a static method and should not be called using thread instances, it is misleading.
Also stopping a thread does not necessarily mean it will invoke the other thread. Just remember when it comes to threading, very little is guaranteed.
One more thing :
thread1.run(); // This is incorrect
use thread1.start()
Directly calling run() method does not start a new thread. You need to call start() method to start a new thread. Calling run method directly will execute the contents of the run method in the same thread(from where it is invoked)
In Java if I have a class that creates threads from the constructor (by calling some functions of that class) and I create an object of that class in my main method. Does the main method wait until all the threads are done or does it continue to the next line?
for example:
public static void main(String[] args) {
WorksWithThreads obj = new WorksWithThreads ( );
//does something else - does this line happen after all the 9 threads finished their job?
}
class WorksWithThreads(){
public WorksWithThreads(){
for(int i=0;i<9;i++)
WithThread tread= new WithThread();
}
private static class WithThread extends Thread {
public WithThread () {
run();
}
public void run(){
//does something
}
}
}
I hope I was not too confusing.. Thank you in advance..
Shiran
If you actually spawn new Threads your main method would continue right after finishing spawning (but before the threads end, assuming they run for sometime)
BUT you are not spawning threads. You are creating instances of the Thread class. To actually spawn new threads you'd have to call start. Calling run() as you do is just a normal method call and processing will only continue after it finished.
You might want to work through the official tutorial about this topic.
No. The very point of threads is that they don't halt execution of the thread that spawns them. main() will continue executing as soon as WorksWithThreads has finished spawning all its threads, but the threads it spawns will execute at the same time as the rest of main.
Yes it will run after the 9 threads are created.Here you have not even start those 9 threads.So before they are executed next line in main will be executed