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
Related
I know this is a very tiny thing and would be quite easy for all you programmers out here, but I am stuck. I am not able to understand why this code snippet is printing out "Dog" instead of "Cat".
Runnable r = new Runnable() {
public void run() {
System.out.print("Cat");
}
};
Thread t = new Thread(r) {
public void run() {
System.out.print("Dog");
}
};
t.start();
Calling start() on a Thread object causes the JVM to spawn a new system thread which then proceeds to call the run method. Its default implementation looks something like this :
private Runnable target; // This is what you passed to the constructor
#Override
public void run() {
if (target != null) {
target.run();
}
}
Since you have overriden this very method in your anonymous Thread subclass declaration, this code never gets called, and the Runnable you injected is simply never used.
Also, whenever possible, leave the Thread class alone and put your code in Runnables instead.
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.
I am writing a java swing program that involves using a thread to update the UI,
The run function in the thread contains a while loop and a sleep timer,
I want to either terminate the while loop or the thread itself when the user presses for example ctrl+c. The thread includes a sleep command, I don't want the user to have to hold down ctrl+c to terminate, I just want to be able to use those keys once.
How is this possible?
public static void main(String[] args) {
.......//Code to set up window
Thread thread = new Thread(){
#Override
public void run() {
while(user has not terminated the program with ctrl+c){
//Do Something
try{
Thread.sleep(5000);
}catch(InterruptedException e){
}
}
}
};
.......//Code to start thread
}
In Java, threads are terminated cooperatively. This means that it requires modifying both the code inside the thread as well as the code outside the thread. Outside the thread, you can signal that the thread should prepare to shutdown by using the Thread.interrupt() method. Inside the thread, you should check Thread.interrupted() to test for interruption (and break from the loop if that is the case). You should also modify your exception handler; the interrupted exception is thrown when Thread.interrupt() was called while the thread was sleeping, so you should modify the content of that handler to break from the loop.
try something like this
class A{
Thread r1Thread;
public static boolean isCtrlCPressed = false;
public static void main(String[] args) {
.......//Code to set up window
MyRun r1 = new MyRun();
r1Thread = new Thread(r1);
r1Thread.start();
}
public void someMethodThatDetectCtrlC(){
r1Thread.interrupt();
}
}
Your Thread
class MyRun implements Runnable{
#Override
public void run() {
// TODO Auto-generated method stub
try{
Thread.sleep(5000);
}catch(InterruptedException e){
}
}
}
Make a boolean called "running"
Change your while loop to while(running)
Add a keylistener, make it listen for Ctrl + C.
If it hears Ctrl + C, set running = false.
Since running == false, the while loop will then stop.
I'm starting a thread which loops indefinitely until a certain event occurs. The problem is, I want to start this thread, and then return to the normal execution of my program. However, after starting the thread, the code seems to get stuck.
Code:
public void init()
{
Runnable thread = new Runnable()
{
public void run()
{
while(something)
{
//do something
}
}
};
System.out.println("Starting thread..");
new Thread(thread).run();
System.out.println("Returning");
return;
}
When I start this, I get the output "Starting thread" but I don't get "returning" until the conditions for the while loop in the run() stop being true.
Any ideas how I can make it work asynchronously?
Use start rather than run to start a Thread. The latter just invokes the run method synchronously
new Thread(thread).start();
Read: Defining and Starting a Thread
You may try this in your code:-
new Thread(thread).start();
like:-
public void init()
{
Runnable thread = new Runnable()
{
public void run()
{
while(something)
{
//do something
}
}
};
System.out.println("Starting thread..");
new Thread(thread).start(); //use start() instead of run()
System.out.println("Returning");
return;
}
You want to call new Thread(thread).start() instead of run().
Are you sure about your approach? You say:
The thread should loop indefinitely until certain event occurs.
that's an enormous loss of computational resource, the program is principally bound to get slow & fail. You may want to put the thread in wait() mode and catch InterruptedException to wake it up upon occurrence of your event of interest. If this preliminary understanding of what you are trying to accomplish is true then Id' strongly suggest you to revise your approach. Computing resource is expensive, don't waste it in relentless looping.
I have a callback function in which i receive a string.
This string is to be passed to a separate thread for processing since the processing takes time.
Also, since multiple callbacks can come simultaneously, I would like to have a synchronized lock till i pass the string into the new thread. But I do not wish to have the new thread (where processing is going on) to be locked also.
Could someone please help me figure out the design for this?
I have written the following code but in this I think in this no callbacks can be received till the whole processing of the separate thread is also done, thereby defeating the whole purpose of this new thread.
String sLine;
onClick(String line){
synchronized (lock) {
sLine = line;
new Thread(new Runnable() {
#Override
public void run() {
doProcessing(Sline);
}).start();
}
}
Also, since multiple callbacks can come simultaneously, I would like to have a synchronized lock till i pass the string into the new thread.
A: I don't think you need to put a lock here. This string is not accessed by multi-thread.
But I do not wish to have the new thread (where processing is going on) to be locked also.
A: As I see nothing was locked here :) I think it could be better if you do something like that:
Create an class Runner implement Runnable, this class will do processing
Everytime you got callback, use ThreadPoolExecutor to execute this Runner. This help you reuse Thread instance.
Note that: These line code doesn't need to synchronized, put synchronized inside processing method if you need.
// Implement class Runner
public class Runner implements Runnable {
private String mLine;
public Runner(String line) {
mLine = line;
}
#Override
public void run() {
process();
}
public void process() {
// Do processing with mLine
// Put synchronized if you need, it bases on your context
}
}
// Initialize thread pool
private ThreadPoolExecutor executor = new ThreadPoolExecutor(10, 100, 1000, TimeUnit.SECONDS, new LinkedBlockingDeque<Runnable>());
// Execute runner when receiving callback
onClick(String s) {
Runner runner = new Runner(s);
executor.execute(runner);
}
Try changing like below
String sLine;
onClick(final String line){
sLine = line;
new Thread(new Runnable() {
#Override
public void run() {
doProcessing(line);
}).start();
}