I am trying to do following in gui class for notifying registred observers.
public class GUI extends javax.swing.JFrame implements Observer {
public notImportantMethod() {
t = new Thread() {
#Override
public void run() {
for (int i = 1; i <= 10; i++) {
myObject.registerObserver(this);
}
}
};
t.start();
}
}
It gives me error: incompatible types: cannot be converted to Observer How can I use this? I know inside of run there is another context but how could I access it?
this now refers a Thread. You should be able to call GUI.this. For more info, see here .
If you're looking for quick and dirty: (this is not good practice)
public notImportantMethod() {
final GUI self = this;
t = new Thread() {
#Override
public void run() {
for (int i = 1; i <= 10; i++) {
myObject.registerObserver(self);
}
}
};
t.start();
}
}
Otherwise I would recommend looking up a tutorial on multi-threading and/or concurrency in java, like this one: http://winterbe.com/posts/2015/04/30/java8-concurrency-tutorial-synchronized-locks-examples/
#Ishnark has answered it correctly. You should be able to access it via GUI.this, that's all that you need to do.
Related
Ι have the following custom Runnable:
class RandomSum extends Runnable {
public void run() {
float sum - 0;
for(int i = 0; i<1000000;i++){
sum+=Math.random();
}
}
}
And I want to run it like that:
RandomSum s =new RandomSum();
s.retrieveCallback((sum)->{
System.out.println(sum);
});
Thread thread = new Thread();
thread.start();
But I do not know how I should define the method retrieveCallback in RandomSum that accepts a lambda?
You can define retrieveCallback within RandomSum as follows:
public void retrieveCallback(FeedbackHandler feedbackHandler) {
int sum = ...; // Get the value however you like.
feedbackHandler.handleFeedback(sum);
}
And then define this FeedbackHandler interface as:
public interface FeedbackHandler {
void handleFeedback(int sum);
}
Essentially what happens when you pass lambda (sum) -> {...} to retrieveCallback is:
retrieveCallback(new FeedbackHandler() {
#Override
public void handleFeedback(int sum) {
...
}
});
One possible target type of the lambda you've shown is a Consumer. Define a method setCallback accepting a Consumer<Float> and store it as an instance variable. Then invoke it after the for loop.
class RandomSum implements Runnable {
Consumer<Float> callback;
public void setCallback(Consumer<Float> callback) {
this.callback = callback;
}
public void run() {
float sum = 0;
for(int i = 0; i<1000000;i++){
sum += Math.random();
}
callback.accept(sum);
}
}
Caller side
RandomSum s =new RandomSum();
s.setCallback((sum)->{
System.out.println(sum);
});
Or using method references,
s.setCallback(System.out::println);
Preferably you can pass the callback in the constructor.
I have the following code:
public class main {
public static void main(String[] args) {
Thready howdy = new Thready();
Thread howYouDo = new Thread(howdy);
howYouDo.start();
}
}
class Thready implements Runnable{
int hi = 1;
public Thready(){}
public void run() {
for(int i = 0; i < 10; i++) {
System.out.println(++hi);
}
}
}
It runs fine in IntelliJ regardless of the #Override annotation. In Eclipse, it forces you to remove the #Override annotation, and it works. In NetBeans, it warns you to add an #Override annotation, and the code runs, but the THREAD IS NEVER STARTED in NetBeans no matter what. Meaning the console does not print out anything.
What is going on?
I am just trying to create an example program to help me remember how to operate for loops, when I ran it through the compiler. The Compiler said missing return statement. Where do I add it?
Here is the code:
public class LoopExample {
public String bam() {
for (int i = 0; i < 8; i++) {
System.out.println(i);
}
}
}
EDIT
I received an answer, but now the main says 'cannot find symbol'... here is the code for the main:
public class LoopExampleTestDrive {
public static void main(String[] args) {
bam looper = new bam();
System.out.println(looper);
}
}
I would advise you to try to understand how Object Oriented languages work first.
That being said, the main reason why your code doesn't work, is because you try to make an object of the class bam with new bam(). This class unfortunately doesn't exist as it is only a method in a class. My solution would look like:
public class LoopExample {
public void bam() {
for (int i = 0; i < 8; i++) {
System.out.println(i);
}
}
public static void main(String[] args) {
new LoopExample().bam();
}
}
As I said: try to understand object oriented programming first, before trying to continue programming in Java. It is too essential to be able to write working code.
PS: just to be complete, the best way to write what you want to do, would look as follows.
public class LoopExample {
public static void main(String[] args) {
for(int i = 0; i < 8; i++) {
System.out.println(i);
}
}
}
Change the signature of your method. Replace public String bam() with public void bam(). voidmeans that you return nothing instead of a String as before.
For further information see http://www.tutorialspoint.com/java/java_methods.htm
Thread t = new Thread(new Runnable() { public void run() {} });
I'd like to create a thread this way. How can I pass parameters to the run method if possible at all?
Edit: To make my problem specific, consider the following code segment:
for (int i=0; i< threads.length; i++) {
threads[i] = new Thread(new Runnable() {public void run() {//Can I use the value of i in the method?}});
}
Based on Jon's answer it won't work, since i is not declared as final.
No, the run method never has any parameters. You'll need to put the initial state into the Runnable. If you're using an anonymous inner class, you can do that via a final local variable:
final int foo = 10; // Or whatever
Thread t = new Thread(new Runnable() {
public void run() {
System.out.println(foo); // Prints 10
}
});
If you're writing a named class, add a field to the class and populate it in the constructor.
Alternatively, you may find the classes in java.util.concurrent help you more (ExecutorService etc) - it depends on what you're trying to do.
EDIT: To put the above into your context, you just need a final variable within the loop:
for (int i=0; i< threads.length; i++) {
final int foo = i;
threads[i] = new Thread(new Runnable() {
public void run() {
// Use foo here
}
});
}
You may create a custom thread object that accepts your parameter, for example :
public class IndexedThread implements Runnable {
private final int index;
public IndexedThread(int index) {
this.index = index;
}
public void run() {
// ...
}
}
Which could be used like this :
IndexedThread threads[] = new IndexedThread[N];
for (int i=0; i<threads.length; i++) {
threads[i] = new IndexedThread(i);
}
Can someone please help me out.
I need to use two threads in a way that one thread will run permanently while(true) and will keep track of a positioning pointer (some random value coming in form a method). This thread has a logic, if the value equals something, it should start the new thread. And if the value does not equal it should stop the other thread.
Can someone give me some code snippet (block level) about how to realize this?
Create a class that implements Runnable. There you'll make a run() method.
Like:
public class StackOverflow implements Runnable{
private Thread t = null;
public void run(){
}
public void setAnotherThread(Thread t){
this.t = t;
}
}
On the main class, you'll create 2 instances of Thread based on the other class you created.
StackOverflow so1 = new StackOverflow();
StackOverflow so2 = new StackOverflow();
Thread t1 = new Thread(so1);
Thread t2 = new Thread(so2)
Then you set one thread in the other, so you can control it.
t1.setAnotherThread(so2);
t2.setAnotherThread(so1);
Then you do what you need to do.
Ok if I'm not mistaken, you want to have one class that could be run as a "Thread" or as a (lets call it) a "sub-Thread".
But how to do that with one run method? just declare a boolean variable that specifies whether the thread object is a sub-thread or a parent thread, and accordingly declare two constructors, one would create a parent thread and the other would create a sub thread, and to be able to stop the sub-thread declare another variable called stop that is default to false.
class ThreadExample extends Thread {
private boolean sub = false;
private ThreadExample subThread = null;
public boolean stop = false;
public ThreadExample() {
}
public ThreadExample(boolean sub) {
this.sub = sub;
}
public void run() {
if (sub) {
runSubMethod();
} else {
runParentMethod();
}
}
public void runParentMethod() {
boolean running = true;
while (running) {
if (getRandomValue() == some_other_value) {
if (getSubThread().isAlive()) {
continue;
}
getSubThread().start();
} else {
getSubThread().makeStop();
}
}
}
public void runSubMethod(){
while(true){
//do stuff
if (stop)
break;
}
}
public int getRandomValue() {
//your "Random Value"
return 0;
}
private ThreadExample getSubThread() {
if (subThread == null) {
subThread = new ThreadExample(true);
}
return subThread;
}
public void makeStop(){
stop = true;
}
}
Here is a simple idea how you can implement as many threads as you like in a class:
class MultipleThreads{
Runnable r1 = new Runnable() {
public void run() {
... code to be executed ...
}
};
//-----
Runnable r2 = new Runnable() {
public void run() {
... code to be executed ...
}
};
//--- continue as much you like
public static void main (String[] args){
Thread thr1 = new Thread(r1);
Thread thr2 = new Thread(r2);
thr1.start();
thr2.start();
}
}
Hope it helps!!
For communicating between the two threads, one simple solution is to set a boolean type volatile static variable, and have it set from one thread and put it in while(flag) condition in the other thread.
You can control the other thread using this method.
And if you have waiting processes or Thread.sleep() and you want to break the thread without having it to finish it, your interrupts by catching the exception.