Alright, I'm new to threading, so my question might be pretty dumb. But what I want to ask is, I have this class, let's say its name is MyClass.java. And then inside one of its methods is callThread(), which I want to print something out, sleep, and return control to MyClass.java's method. How do I do that?
Currently, my code goes something like this:
class MyClass {
void method()
{
MyThread thread = new MyThread();
thread.run();
// do some other stuff here...
}
}
And then, this will be the MyThread:
class MyThread implements Runnable {
public void run()
{
while (true)
{
System.out.println("hi");
this.sleep(1000);
}
}
}
I was hoping that MyThread would print "hi", pass back control to MyClass, and then print "hi" again one second later. Instead, MyThread freezes up my entire program so having it in there doesn't work at all...
Is there any way around this?
You should be callig thread.start()
More on that in the manual: Defining and Starting a Thread
You must have to call start() method of Thread class.
MyThread thread = new MyThread();
Thread th=new Thread(thread);
th.start();
sleep() is an instance method of Thread class and MyThread class is not a thread (It's a runnable) so you need to use Thread.currentThread().sleep() method.
while (true)
{
System.out.println("hi");
try{
Thread.currentThread().sleep(1000);
}catch(Exception ex){ }
}
Read this tutorial for more info on thread.
Related
I was going to use threads for each sound in a game engine I'm making. The problem is, whenever I make a new thread that has a while(true) statement, the other thread stops running.
I made a class to test this, and it only prints "goodbye", not "hello". I was wondering how to make the two threads run at the same time.
public class testor {
public static void main(String args[]){
testor test=new testor();
test.runTest();
}
class threadTest implements Runnable{
#Override
public void run() {
while(true){
System.out.println("goodbye");
}
}
}
public void runTest(){
threadTest test=new threadTest();
test.run();
while(true){
System.out.println("hello");
}
}
}
Since you are doing test.run(); you are only calling the method of that class but not starting the thread.
So in order to answer your question: there is no such a thread stopping the other thread from running? because you have only one Thread that is looping for ever and printing the message System.out.println("goodbye");
If that method is not looping for ever, it would return to the runTest method and then you would see the System.out.println("hello");
Summary:
For starting a Thread use the Thread::start method and not the run.
Using (new ThreadTest()).run() does not start a new Thread, but just invokes the run() method in the current thread.
To run the code in a separate thread do:
(new Thread(new ThreadTest())).start();
That's because you're not creating a new thread. Just naming a class something containing "thread" will not make it a thread, and a Runnable is no thread - it's a class like any other, with no special semantics or behaviour.
It's only special in that you can pass it to a Thread for execution.
public class Testor {
public static void main(String args[]){
Testor test=new Testor();
test.runTest();
}
class MyRunnable implements Runnable{
#Override
public void run() {
while(true){
System.out.println("goodbye");
}
}
}
public void runTest(){
Thread testThread = new Thread(new MyRunnable());
testThread.start();
while(true){
System.out.println("hello");
}
}
}
You should probably also adhere to the Java coding standards regarding your class and variable names if you do not want your code to look like an alien when combined with most other existing Java code.
Additionally, multithreading is more than just being able to start a new thread. You should also read about synchronisation issues - it's more complicated to do correctly than you might imagine.
Your run method contains an infinite loop.
The runTest() method creates the thread which means you'll have 2 execution stacks the main stack, and the runnable threadTest stack.
since you're running the thread method first that contains an infinite loop, you'll always get the output "good Bye".
Remove the infinite loop from run() method.
Im not sure exactly what the problem is but for some reason I cant get threads from two classes to run at the same time. I can get multiple threads from one class to run at the same time, but when I try to start another class nothing happens.
public professor(){
prof = new Thread();
prof.start();
System.out.println("Prof has started1");
}
public void run(){
try{
System.out.println("Prof has started2");
prof.sleep(600);
//do more stuff
}
catch(Exception e){
System.out.println("Prof error");
}
This is how I started my second class, the first one is started in the exact same way and runs fine. With this class however "Prof has started1" gets displayed, but the second one never does.
Am I missing something?
I think this is the reason
prof = new Thread();
prof.start();
This code will never call your own run() method, if your class implements the runnable interface, you should do this
prof = new Thread(this)
prof.start()`
You don't provide the full delcartion the Professor class so the exact solution may vary but the main point that I see is this: you create an instance of the Thread class and then invoke .start():
prof = new Thread();
prof.start()
Alas, the Thread class by itself does not do any thing when you call .start() on it. you need to tell it what is the action that you want it to carry out once it has been start()-ed. There are several ways to do so, but I will go with this:
public professor() {
prof = new Thread(new Runnable() {
public void run() {
try {
System.out.println("Prof has started2");
Thread.currentThread().sleep(600);
//do more stuff
}
catch(Exception e){
System.out.println("Prof error");
}
}
});
prof.start();
System.out.println("Prof has started1");
}
public void run() {
}
That is: create an instance of Runnable in which you override the run() such that it does whatever you want it to do. Then pass this instance of Runnable to the constructor of the Thread object you're creating. When you subsequently invoke .start() the run() method of that Runnable will get executed.
This question already has answers here:
Please explain the output from Thread run() and start() methods
(4 answers)
Closed 8 years ago.
I was working on Threads when a question struck to my mind..If we can directly call run() method with the object of a class like any ordinary method then why do we need to call Thread.start() to call run() method..I tried both the methods as shown and got same result with both of them
First attempt by calling run() method directly
class Abc extends Thread
{
public void run()
{
for(int i=0;i<5;i++)
{
System.out.println("Abc");
}
try
{
Thread.sleep(100);
}catch(Exception e)
{
System.out.println("Error : "+ e);
}
}
}
class Xyz extends Thread
{
public void run()
{
try
{
for(int i=0;i<5;i++)
{
System.out.println("Xyz");
}
Thread.sleep(100);
}catch(Exception e)
{
System.out.println("Error : "+ e);
}
}
}
public class ThreadDemo
{
public static void main(String[] args)
{
Abc ob=new Abc();
Xyz oc=new Xyz();
ob.run();
oc.run();
}
}
Second attempt by calling Thread.start()
public class ThreadDemo
{
public static void main(String[] args)
{
Abc ob=new Abc();
Xyz oc=new Xyz();
Thread t1,t2;
t1=new Thread(ob);
t2=new Thread(oc);
t1.start();
t2.start();
}
}
If you call run() directly, the code gets executed in the calling thread. By calling start(), a new Thread is created and executed in parallel.
If you directly call run(), then all the work will be done on the main thread.
By using Thread.start, then it will executed on a new thread other than the main thread ;)
To observe what the difference is, increase your sleep calls to something longer like 10 seconds. This will make it obvious that you need Thread.start to avoid the first task waiting on the second.
In the case where you use Thread.start, you will see that output of both threads appears immediately.
In the case where you use run, you will see that the output of the first appears, then a 10 second delay, then the output of the second.
If you call run() method directly then code will run inline. To run the code in separate thread it is necessary to call Thread.start().
When you call start() method on thread reference it create span entirely context area. Then thread will have independent stack from where you are calling. More over start() invokes OS native thread to start it in separate memory context.
While run() method invocation considered as simple method call, and you won't have benefit of concurrency as its executing is current stack.
So I have two files, the first is a swing class and the second is my thread class. When I run my thread for for some reason it doesn't run, I tried by placing some print statements to see if my program would ever get there but none of them ran.
My thread class
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
class CheckFiles implements Runnable {
public void run() {
while (!UserInterface.stop) {
try {
String line;
BufferedReader b = new BufferedReader(new FileReader(UserInterface.location));
while((line = b.readLine()) != null) {
System.out.println(line);
}
} catch (IOException e) { System.out.println(e); }
}
}
}
In my UserInterface class I start the method by doing the following
System.out.println(stop); //prints true
loadFile.setEnabled(false); //not important
status.setText("Checking Files"); //not important
stop = false;
System.out.println(stop); //prints false
new CheckFiles(); //start thread
Is there something that is stopping my thread from running or am I doing it wrong?
You are creating a class that can be used to start a thread, but you are not starting it.
Several solutions are possible:
Solution 1:
Change the type to extend Thread
class CheckFiles extends Thread {
...
}
and change the last line to
(new CheckFiles()).start();
Solution 2:
Keep CheckFiles a Runnable, and change the last line to
(new Thread(new CheckFiles())).start();
You should'nt make the class extend thread, rather do something like
Thread t = new Thread(new CheckFiles());
t.start();
At the moment you only made your class Runnable. You need to create and start your thread. Please take a look at http://docs.oracle.com/javase/tutorial/essential/concurrency/simple.html.
Thread t = new Thread(new CheckFiles());
t.start();
The main differences between extending Thread, and implementing your target Runnable is that when extending Thread you are associating the Thread with the object you are creating. By making your Object runnable, you are able to associate your Thread with many runnable objects..
You just have created an instance of the class that is supposed to be a Thread! You have to actually declare a Thread and start it. e.g. new Thread(new CheckFiles()).start(); to create an instance of the thread, the object and start it.
I need to implement thread.start() method in my java code. Please let me know through an example of overriding of thread.start() method and how it works?
You should not. Override run instead
You can override start as any other method
Thread myThread = new Thread() {
#Override
public void start() {
// do something in the actual (old) thread
super.start();
}
#Override
public void run() {
// do something in a new thread if 'called' by super.start()
}
};
but you must call super.start() to create a new thread and have run() called in that new thread. The original start does some magic (native code) that you hardly can mimic.
If you call run() directly from within your start() (or any other method), it is executed in the actual thread as a normal method, not in a new thread. There is no reason to use a Thread if you don't want to run some code in a new thread.
You must put your decision logic in the run() method, maybe using some variable set in the constructor (or another method, eventually in start) if that is really needed. I can not find any reason for needing this variable, it should be enough to test the condition in run() as already suggested elsewhere.
class MyThread extends Thread {
private final boolean flag;
public MyThread(boolean someCondition) {
flag = someCondition;
}
// alternative
// #Override
// public synchronized void start() {
// flag = <<someCondition>>
// super.start();
// }
#Override
public void run() {
if (flag) {
// do something like super.run()
} else {
// do something else
}
}
}
but it would be easier to understand and maintain if you do it like #Henning suggested!
It's also a more object oriented solution...
As others said, overriding Thread.start() is not the way to do it. Usually, I wouldn't override Thread.run() either, but use a Runnable.
If you have to decide which method to run after the thread has been spawned, you could do something like this:
final Runnable runnableA = ...;
final Runnable runnableB = ...;
Runnable r = new Runnable() {
#Override
public void run() {
if (...) {
runnableA.run();
} else {
runnableB.run();
}
}
}
Thread thread = new Thread(r);
thread.start();
If, as you say, you have a superclass and a subclass where the run() method is overidden, you can just rely on late binding and the proper method will be invoked automatically:
Runnable couldBeAOrB = ...;
Thread thread = new Thread(couldBeAOrB);
thread.start();
You don't override the start, you override the "run". You can simply implement a thread by:
new Thread() {
public void run() {
//your code here
}
}.start();
//start will call the logic in your run method
Actually, you can call run() to run a thread instead of start() to run a thread. But there is a little difference.
Suppose you create two threads:
Thread t1 = new Thread();
Thread t2 = new Thread();
Case 1 : If you call "t1.run()" and "t2.run()" one after another they will start to run t1 and t2 synchronously (sequentially).
Case 2 : If you call "t1.start()" and "t2.start()" one after another they will call their run() methods and start to run t1 and t2 asynchronously (in parallel).
Agree with Schildmeijer, don't override start, override run() instead.
In fact, although start can be overridden (it's not final), it calls the native start0 method which in turn will cause the VM to call the run method (actually from the context of a native thread/process). The native start0 method has private access, so even if you overrode the start, I can't see how you could reproduce the affect.
The client calling start() is within a thread (lets say, the main thread), it's not until the run method has done its thing that another thread will be spawned.
Take a look at the Sun (ahem, Oracle) tutorial on threads at http://download.oracle.com/javase/tutorial/essential/concurrency/index.html, in particular the section on starting threads.
class Worker implements Runnable{
public void run(){
if("foo"){
runFoo();
} else {
runBar();
} }
private void runFoo(){
// something }
private void runBar(){
// else }
}
I'm pretty sure, you needn't to overwrite the start-Method.
By the way: Take al look at java.util.concurrent.Callable
http://download.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/Callable.html
It is discouraged to override Thread, if possible create an implementation of the Runnable interface instead and run that on a thread. This can also be done with a lambda expression, making everythin super short and simple.
// create a new thread and give it a Runnable with a lambda expression and a custom name
Thread thread = new Thread(() -> {
// put your code here
}, "CustomThreadName");
// start it
thread.start();
If we provide our own implementation of start method then it will work like a normal method call and will work on the current thread stack only. New thread will not be created.
Yes the start() method can be overridden. But it should not be overridden as it is implementation in thread class has the code to create a new executable thread and is specialised.
We can override start/run method of Thread class because it is not final. But it is not recommended to override start() method
class Bishal extends Thread {
public void start()
{
System.out.println("Start Method");
}
public void run()
{
System.out.println("Run Method");
}
} class Main{
public static void main(String[] args)
{
Bishal thread = new Bishal();
thread.start();
System.out.println("Main Method");
}
}
when we are calling start() method by an object of Bishal class, then any thread won’t be created and all the functions are done by main thread only.