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.
Related
i am writing code from online to create a chat application. After trouble shooting my program to find out why it is not working I have discovered that the code inside my run method here is not being reached. here is the snippet of code
public void listen()
{
listen = new Thread("Listen") {
public void run()
{
writeMessage("Working in here");
while (true) {
String message = client.receive();
if (message.startsWith("/c/")) {
client.setID(Integer.parseInt(message.substring(3, message.length())));
writeMessage("Successfully connected to server" + client.getID());
}
}
}
};
}
It is reaching the listen method itself, because if i use the write message command before i declare the thread, it prints out the message for me, any idea from looking at this why it will not enter any further?
Thanks
Calling start() on your Thread would do it:
public void listen()
{
listen = new Thread("Listen") {
public void run()
{
writeMessage("Working in here");
while (true) {
String message = client.receive();
if (message.startsWith("/c/")) {
client.setID(Integer.parseInt(message.substring(3, message.length())));
writeMessage("Successfully connected to server" + client.getID());
}
}
}
};
listen.start(); // <-- Add this line
}
Also, you typically don't want to extend Thread (which you are doing here with an anonymous class). Usually you'll want to create a Runnable and pass that to Thread's constructor instead:
Runnable r = new Runnable() {
#Override
public void run()
{
// Do some work here
}
};
Thread listen = new Thread(r, "Listen");
listen.start();
Or even better, use an Executor, there aren't many good reasons to create your own Thread objects.
Certainly working with appropriate Execotor or even better ExecutorService is more appropriate way of working with threads today. Read about it here. But if you insist on working the old way then you need to invoke start() method of your thread. Methods start() and run() do the same thing, only run() execute your thread sequentially i.e. in the same thread where you invoked it and start() actually starts a new thread where your code is executed which is what you wanted in the first place
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.
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.
As an addition to my current application, I need to create a separate thread which will periodically do some processing
I've create a new class to do all this, and this class will be loaded on startup of my application.
This is what I have so far :
public class PeriodicChecker extends Thread
{
static
{
Thread t = new Thread(new PeriodicChecker());
while(true)
{
t.run();
try
{
Thread.sleep(5000l);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
}
/**
* Private constructor to prevent instantiation
*/
private PeriodicChecker()
{
}
#Override
public void run()
{
System.out.println("Thread is doing something");
// Actual business logic here, that is repeated
}
}
I want to make constructor private to prevent other people from attempting to instantiate this class accidentally. How can I achieve this?
Also, is there anything bad about my implementation of such requirements? I'm only creating one thread which will run then sleep, have I missed anything obvious? I haven't worked with threads before
Java offers ScheduledExecutorService to schedule and run periodic tasks or tasks with delay. It should provide all the features you need. Timer is another class that offers similar functionalities, but I would recommend the ScheduledExecutorService over Timer for its flexibility of configuration and better error management.
You have some conceptual erros in your code... for example:
You should call start() and not run(), because you are running the method sequentially and not simultaneously.
You can call start() only once, not once in each loop iteration. After that, the thread is in state TERMINATED, you should create a new thread to run it again
You should not create the thread in the static block, it is a bad practice, and maybe the Thread is running before you want it to run.
You should read some examples about thread, it is a little difficult to unserstand at the beginning, and you can have undesired effects very easily.
Here is a little example, that may do something similar to that you want:
public class PeriodicChecker extends Thread
{
#Override
public void run()
{
while(true) {
System.out.println("Thread is doing something");
Thread.sleep(5000);
}
}
}
public OtherClass {
public static void main(String args[]) {
Thread t = new PeriodicChecker();
t.start();
}
}
If you want that none can create a new Thread, you could create a singleton, so you will be sure that none is creating more threads.
I'd recommend you to consider Timer class - it provides functionality for periodic tasks execution.
Also you may take a look at "Timer & TimerTask versus Thread + sleep in Java" question discussion - there you can find some arguments and examples.
First of all to answer your specific question, you have already achieved your objective. You have declared your constructor to be private meaning no external class can call it like new PeriodicChecker().
Looking at your code however, there are a number of other problems:
Firstly, you are creating an instance of your class within its own static constructor. The purpose of a static constructor is to initialise any static state that your class may have, which instances of your class may then depend on. By creating an instance of the class within the static constructor, all of these guarantees go out the window.
Secondly, I don't think your thread is going to behave in the way you expect it to behave, primarily because you don't actually start another thread :). If you intend to start a new thread, you need to call the start() method on that thread object. Calling run() as you do does not actually create a new thread, but simply runs the run() method in the current thread.
Nowadays when you want to create a new thread to do something, the reccomended way of achieving this is to not extend Thread, but instead implement the Runnable interface. This allows you to decouple the mechanism of the thread, from the behaviour you intend to run.
Based on your requirements, I would suggest doing away with a top-level class like this, and instead create either a private inner class within your application start-up code, or even go for an anonymous inner class:
public class Main {
public static void main(String[] args) {
new Thread(new Runnable() {
#Override
public void run() {
while(true) {
System.out.println("Thread is doing something");
Thread.sleep(5000);
}
}
}).start();
}
}
It is almost never right to extend Thread. If you ever find yourself doing this, step back, take a look and ask yourself if you really need to change the way the Thread class works.
Almost all occurances where I see extends Thread the job would be better done implementing the Runnable interface or using some form of Timer.
I have a problem with java threads:
public class MyClass{
public void Core(){
runTools(); //here I would like to call runTools() method
}
public void runTools(){
final String run_tool ="cmd.exe /C sources.exe";
Runnable doRun = new Runnable() {
public void run() {
try {
Process tool_proc = Runtime.getRuntime().exec(run_tool);
}
catch (IOException e) {
e.printStackTrace();
}
}
};
Thread th = new Thread(doRun);
th.start();
}
}
If I do this, then I don't know why, but the thread doesn't work. Please give me some ideas to create a thread. I have already been seen lots of examples, but I should some code such as my example here. Thanks!
At first, if you just want to execute an external command and do not bother about its output*, then using a dedicated thread is unnecessary, since the process itself will already run in parallel to your application, so the exec() call will not really hang your programm.
Nevertheless your code looks correct to me. You should check the working directory of your application (maybe cmd.exe cannot find your sources.exe) and evaluate the output the process you start gives you, by directing the streams of tool_proc.getErrorStream() and tool_proc.getInputStream() to System.out or logging them.
EDIT:
* The Java documentation states you always should read the InputStreams of your processes as failing to do so might result in filling up a system buffer, which will eventually hang the process.
problem 1 You create object for Runnable Interface,that is never possible.
Runnable *obj=new Runnable(); // this is not correct
problem 2 You write definition for Run() method with in the another method runTools()
we can create object for a class that implements The Runnable interface.
Due to these your code is not working.
Try the fallowing way
public class MyClassName1 implements Runnable
{
public void start()
{
//here you can call your method:runTools()
runTool();
}
}
public void runTools()
{
final String run_tool ="cmd.exe /C sources.exe";
try
{
Process tool_proc = Runtime.getRuntime().exec(run_tool);
}
catch (IOException e)
{
e.printStackTrace();
}
}
here is my main class of the programe
public class MyClassName2
{
public static void main(String[] ars)
{
Runnable *obj1=new MyClassName1();
Thread t=new Thread(obj);
t.start()
}
I hope this helps to you