My code:
public class MyPanel extends JPanel {
private Thread spawnRnn = new Thread(new SpawnRnn());
public MyPanel() {
spawnRnn.start();
}
public class SpawnRnn implements Runnable {
public void loadData() {}
public void run() {}
}
public class MainRnn implements Runnable {
public void run() {
spawnRnn.loadData(); //<--cannot find symbol. symbol: method loadData()
//location: variable spawnRnn of type Thread
}
}
}
I pointed place where error occurs. What is the reason and how to solve it?
Well, that's an easy one. "spawnRnn" is of type "Thread", not "SpawnRnn"
As the compiler says, spawnRnn is of type Thread, not of type SpawnRnn... it doesn't have a loadData method. You probably want something like this:
public class MyPanel extends JPanel {
private final Thread thread;
private final SpawnRnn spawnRnn;
public MyPanel() {
spawnRnn = new SpawnRnn();
thread = new Thread(spawnRnn);
thread.start();
}
public class SpawnRnn implements Runnable {
public void loadData() {}
public void run() {}
}
public class MainRnn implements Runnable {
public void run() {
spawnRnn.loadData();
}
}
}
This way you have access to the instance of SpawnRnn which was used to create the thread. It's unclear whether you actually need the thread variable, or whether you could just use a local variable in the constructor.
(Also I've made the variables final on the grounds that when you can do so, it makes the code easier to reason about.)
The problem is that spawnRnn is of type Thread not SpawnRnn.
Related
I have a method that I want to call in RunnerClass, in a non-static way in ThreadClass.
public class CallingClass{
CallingClass(){
ClassTwo thread = new ClassTwo();
thread.start();
}
public void someMethod(){}
}
public class ThreadClass extends Thread{
public void run(){
//Some thread logic
CallingClass.someMethod();
}
}
Obviously this won't work. The method is not static (and I'm not allowed to make it static), but in the above example I'm trying to access it in a static way, if only because I feel it best represents what I would like to do.
If it makes sense, I would like for the thread to be able to notify the instance of CallingClass that it needs to call someMethod()
Is there a neat way to do this?
What about creating ClassTwo constructer that gets a parameter with CallingClass type?
public class ThreadClass extends Thread{
CallingClass callingClass;
public ThreadClass(CallingClass callingClass) {
this.callingClass = callingClass;
}
public void run(){
//Some thread logic
callingClass.someMethod();
}
}
And create ClassTwo like this:
public class CallingClass{
CallingClass(){
ClassTwo thread = new ClassTwo(this);
thread.start();
}
public void someMethod(){}
}
You could use ThreadClass as an inner class of CallingClass and call the mothod directly.
public class CallingClass{
CallingClass(){
ClassTwo thread = new ClassTwo();
thread.start();
}
public void someMethod(){}
public class ThreadClass extends Thread{
public void run(){
//Some thread logic
someMethod();
}
}
}
Why we have to create an instance of a class and attach it to the newly created thread object even if both are in the same class?
import java.io.*;
class thread1 implements Runnable{
public void run(){
System.out.println("thread started");
}
public static void main(String args[]) throws Exception{
Thread t1=new Thread(new thread1());
t1.start();
}
}
You don't have to create a Runnable to perform custom code within a new Thread. It's also possible to create a subclass of thread directly.
public class WorkerThread extends Thread{
#Override
public void run() {
// TODO Auto-generated method stub
super.run();
// DO SOMETHING
}
}
public class MainClass {
public static void main(String[] args){
new WorkerThread().start();
MainClass mc = new MainClass();
mc.startThread();
}
private void startThread(){
Thread t = new WorkerThread();
t.start();
}
}
I think you have two questions in one:
1.) How to work with a Thread in Java? The answer of Fizer Khan is an example of this.
2.) How do static methods work in java? If you have a static method you are, in a maner of speaking, on a "static layer". You have no "this" reference because there is not object on this layer. Only if you create an instance you can access instance fields and non static methods on this object.
If you add a second static method, you can do the same stuff as in your main method, because both are static. This is rudementary look at this question: https://stackoverflow.com/questions/18402564/how-do-static-methods-work
pulblic class Thread1 implements Runnable{ //name should be upper case
public void run(){
System.out.println("thread started");
}
public static void main(String args[]) throws Exception{ //static method
Thread t1=new Thread(new Thread1()); //t1 is a local reference to an object on the heap - no specil magic here
t1.start(); //call to an "instance" method, can only be performed on an object.
}
There are two ways to write threads.
public class ThreadX implements Runnable {
public void run() {
//Code
}
}
/* with a "new Thread(new ThreadX()).start()" call */
public class ThreadY extends Thread {
public ThreadY() {
super("ThreadY");
}
public void run() {
//Code
}
}
/* with a "new ThreadY().start()" call */
public class MainClass {
private Thread threadX = new Thread(new ThreadX());
private Thread threadY = new ThreadY();
public static void main(String[] args){
// Call threads
threadX.start();
threadY.start();
// some more threads
new Thread(new ThreadX()).start();
new ThreadY().start();
}
}
When you extends Threads, You usually extend a class to add or modify functionality. So, if you don't want to overwrite any Thread behavior, then use Runnable.
I tried using the constructor of a class which implements Runnable Interface. But I was surprised to see it was never called. The run() method was called, however, the constructor was never called. I have written a simple sample code to show the phenomenon. Can anyone explain why this is happening?
public class MyRunner implements Runnable {
public void MyRunner() {
System.out.print("Hi I am in the constructor of MyRunner");
}
#Override
public void run() {
System.out.println("I am in the Run method of MyRunner");
}
public static void main(String[] args){
System.out.println("The main thread has started");
Thread t = new Thread(new MyRunner());
t.start();
}
}
Change public void MyRunner() to public MyRunner() (no return type). public void MyRunner() is not a constructor, it's a method. Constructor declarations don't have a return type.
You have a default Constructor there, since you don't define any constructor. And, the default Constructor was called internally.
A Constructor can't have return type. In your case, public void MyRunner() {} is a method. remove void from you Constructor signature.
Constructor is a special method which does not have return type and its name is same as Class name so remove void from method name to make it constructor.
public class MyRunner implements Runnable {
public MyRunner() {
System.out.print("Hi I am in the constructor of MyRunner");
}
#Override
public void run() {
System.out.println("I am in the Run method of MyRunner");
}
public static void main(String[] args) {
System.out.println("The main thread has started");
Thread t = new Thread(new MyRunner());
t.start();
}
}
This will work and your constructor will be called.
I have a class from which I am calling a new thread.
public class MainClass{
private void cleardata() {
// do something on a separate thread
new Thread(new Runnable() {
#Override
public void run() {
//Do Something
//After this I would like to notify my MainClass that some thing has been done and pass a value.
}
}
}
private void callbackFunc(int a){
// Do something based on value of a
}
}
I have a function in my MainClass. But how do i call this function from my new thread, so as to receive a callback.
Thanks.
You should just be able to call the method in MainClass by its name just as if you were calling from directly inside MainClass itself (as opposed to from the inner class).
If a method name you want to call happens to conflict with one that your inner class has inherited from Object then you can prefix the call with MainClass.this, e.g. MainClass.this.toString() calls toString on MainClass, whereas just toString() calls it on the inner class instance.
In such a case pass the instance of MainClass to the thread class ((during creation)) so that it can call method on it. Having inner class as suggested by others is also a good option.
Something similar-
class MainClass {
private void cleardata() {
new Thread(new MyThread(this)).start();
}
}
class MyThread implements Runnable {
private MainClass mc;
MyThread(MainClass mc) {
this.mc = mc;
}
public void run() {
// do something
// mc.someMethod();
}
}
public class MainClass{
private void cleardata() {
// do something on a separate thread
new Thread(new Runnable() {
#Override
public void run() {
callBackFunc(result);
}
}
}
private void callBackFunc(int a) {
}
}
Just do it:
public class MainClass{
private void cleardata() {
// do something on a separate thread
new Thread(new Runnable() {
#Override
public void run() {
//Do Something
notifyTheClass("a parameter");
}
}
private void notifyTheClass(String aParam) {
//..do something else
}
}
}
But it is not related to threads, this is about inner classes. If you want the main thread to wait until the new thread is finishes, use Futures for a result. Or use some other multithreading primitives.
Consider following SWT code example:
http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.swt.snippets/src/org/eclipse/swt/snippets/Snippet151.java?view=co
How can I separate the inline defined class?
Thread thread = new Thread() {
public void run() {
...
}
};
I want to define a separate class which updates the table just like it does here. How do I pass the list back to the table? Example code?
Just create a class which extends Thread.
public class Task extends Thread {
public void run() {
// ...
}
}
and create it as follows:
Task task = new Task();
The normal practice is however to implement Runnable:
public class Task implements Runnable {
public void run() {
// ...
}
}
Or if you want a Thread which returns a result, implement Callable<T> where T represents the return type.
public class Task implements Callable<String> {
public String call() {
// ...
return "string";
}
}
Both can be executed using the ExecutorService.
I would not create a class that extends Thread. It's more likely that you'll have a class that implements Runnable and provides access to private data members:
public class YourTask implements Runnable
{
private ResultClass result;
public void run() { }
public ResultClass getResult() { return result; }
}
Have a look at java.util.concurrent packages and the new FutureTask. I think that's a better bet.
You can work passing parameters or setting globally visible attributes, example:
class Foo
{
public static String baz = "baz";
private String bar = "bar";
void startThread()
{
MyThread thread = new MyThread(bar);
thread.start();
}
}
class MyThread extends Thread
{
String ref;
MyThread(String ref)
{
this.ref = ref;
}
public void run()
{
// it can work with passed parameter
System.out.println(ref);
// but also with globally visible variables
System.out.println(Foo.baz);
}
}