Put Java Threading Class into a separate class - java

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);
}
}

Related

Calling a method from the class that created a thread, in the thread

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();
}
}
}

Java simple callback

It is basic problem. I have class A which gives some task to class B. When class B finish the tast it must notify class A. I want register A class method as callback in class B.
I really want do it in this way, not by observer pattern with interface Observable.
public class A
{
public void A()
{
B b = new B()
b.registerCallback(callback);
}
private void callback()
{
}
}
public class B
{
private ???? callbackoNotify;
public class registerCallback(??? callback)
{
callbackoNotify = callback;
}
public void notify()
{
callback();
}
}
You can define an interface for the callback.
interface Callback{
void call();
}
Then, let class A implement it.
class A implements Callback{
private B b;
public A(){
b = new B();
b.registerCallback(this);
}
// Implementation of the callback interface
public void call(){
}
}
Then, let class B to handle the callback.
public class B
{
private Callback callbackoNotify;
public class registerCallback(Callback callback)
{
callbackoNotify = callback;
}
public void notify()
{
callbackNotify.call();
}
}
But in the above scenario, callbackNotify can be null. Therefore, it is better if you can pass that callback in the constructor to B.
Hope you got the idea.
You can do this without callbacks as well. Here's an example:
A a = ...
B b = ...
Let's say b has a doTask method like this:
public void doTask(Runnable task);
A can now call it like this:
b.doTask(() -> {System.out.println("Hi There");});
However, A will not be informed when the task gets completed. You could simply change the task like this:
Runnable taskForB = () -> {System.out.println("Hi There");};
Runnable wrapperForTaskWithCallback = () -> {
taskForB.run();
taskWasFinished();
};
And then run the wrapper task instead:
b.doTask(wrapperForTaskWithCallback);
And give A a method:
public void taskWasFinished();

Callback from new thread to class from which thread was initiated

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.

Cannot find method in inner class

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.

How to invoke two run methods in one java file

below is the code where i need to invoke 2 run methods for 2 different threads any way this can be done. please help on this.
public class QuestionList extends ListActivity implements Runnable {
//This below thread will call the run method
Thread thread = new Thread(QuestionList.this);
thread.start();
//can i have one more thread which call run1() method any idea
}
public void run() {
}
You cannot have two run() methods of course, and I suggest not using the same for both Threads (with a of if() statement to determine which behaviour to apply).
Instead you should create two distinct classes (why not inner classes) to implement these distinct behaviours. Something like:
public class QuestionList extends ListActivity {
class BehaviourA implements Runnable {
public void run() {
}
}
class BehaviourB implements Runnable {
public void run() {
}
}
private void somewhereElseInTheCode() {
BehaviourA anInstanceOfBehaviourA = new BehaviourA();
Thread threadA = new Thread(anInstanceOfBehaviourA);
threadA.start();
BehaviourB anInstanceOfBehaviourB = new BehaviourB();
Thread threadB = new Thread(anInstanceOfBehaviourB);
threadB.start();
}
}
The good thing with inner classes is that they can access to the members of QuestionList, and this seems to be what you are willing to do.
public class QuestionList extends ListActivity {
//This below thread will call the run method
Thread1 thread1 = new Thread(this);
thread1.start();
Thread2 thread2 = new Thread(this);
thread2.start();
}
class Thread1 implements Runnable
{
public void run() {
}
}
class Thread2 implements Runnable
{
public void run() {
}
}

Categories