I'm trying to create two classes that extends from Thread, I know how to create one class.
public class Main {
class Thred1 extends Thread {
public void run() {
System.out.println("I'm watching a video...");
}
}
class Thred2 extends Thread {
public void run() {
System.out.println("I'm eating...");
}
}
public static void main (String[] args) {
Thred1 t11 = new Thred1();
Thred2 t12 = new Thred2();
t11.start();
t12.start();
}
}
And got Main.java:15: error: non-static variable this cannot be referenced from a static context
Is there better way to implement my idea?
Your problem is with inner classes and not with threads , try to put all this code in the same file Main.java :
class Thred1 extends Thread {
public void run() {
System.out.println("I'm watching a video...");
}
}
class Thred2 extends Thread {
public void run() {
System.out.println("I'm eating...");
}
}
public class Main {
public static void main (String[] args) {
Thred1 t11 = new Thred1();
Thred2 t12 = new Thred2();
t11.start();
t12.start();
}
}
Another possible solution is to use static classes instead of the member inner classes used in your code :
public class Main {
static class Thred1 extends Thread {
public void run() {
System.out.println("I'm watching a video...");
}
}
static class Thred2 extends Thread {
public void run() {
System.out.println("I'm eating...");
}
}
public static void main(String[] args) {
Thred1 t11 = new Thred1();
Thred2 t12 = new Thred2();
t11.start();
t12.start();
}
}
Or simply you can use Lambda expression , Thread class have a constructor who accept a Runnable as parameter , Runnable is a functional interface so you can pass a Lambda expression as argument like that :
public class Main {
public static void main(String[] args) {
Thread t11 = new Thread(()->System.out.println("I'm watching a video..."));
Thread t12 = new Thread(()->System.out.println("I'm eating..."));
t11.start();
t12.start();
}
}
Related
Let's suppose I have this class:
public class Myclass {
method1();
method2();
method3();
}
I want to know if there's a way to run all 3 methods in different threads simultaneously.
Is there a way to create a class MyThread :
public class MyThread{
//implementation
}
in way that it can accept as a parameter myclass::method1()
so that my main function looks something like this:
public static void main(String[] args) {
Myclass myclass = new Myclass();
MyThread mythread1 = new MyThread();
MyThread mythread2 = new MyThread();
MyThread mythread3 = new MyThread();
mythread1(myclass.method1());
mythread2(myclass.method2());
mythread3(myclass.method3());
}
I want mythread() to RUN method() in a thread and NOT use the output of it in a thread.
public class HelloRunnable implements Runnable {
private MyClass myClass;
private boolean execMethod1;
private boolean execMethod2;
private boolean execMethod3;
public HelloRunnable(MyClass myClass, boolean execMethod1, boolean execMethod2, boolean execMethod3) {
this.myClass = myClass;
this.execMethod1 = execMethod1;
this.execMethod2 = execMethod2;
this.execMethod3 = execMethod3;
}
public void run() {
if(execMethod1) myClass.method1();
else if(execMethod2) myClass.method2();
else if(execMethod3) myClass.method3();
}
public static void main(String args[]) {
MyClass myClass = new MyClass();
(new Thread(new HelloRunnable(myClass, true, false, false))).start();
(new Thread(new HelloRunnable(myClass, false, true, false))).start();
(new Thread(new HelloRunnable(myClass, false, false, true))).start();
}
}
If you're using Java 8 you can do this sort of thing:
public static void main(String[] args) {
new Thread(MyClass::method1).start();
new Thread(MyClass::method2).start();
new Thread(MyClass::method2).start();
}
In Java 7 and below there's more to the syntax:
public static void main(String[] args) {
new Thread (new Runnable () {
#Override
public void run ()
{
method1 ();
}
}).start();
}
I've only shown one method for brevity - you must repeat everything from new Thead through start() for each method you want to call.
I stripped everything out to see if I could narrow down my problem and figure it out but I'm embarrassed to say I'm still stumped. Can someone please explain to me why my IDE cannot resolve 'start'? I'm sure it's a stupid mistake :(
public class main {
Thread messageThread = new Thread(new MessageLoop());
messageThread.start();
class MessageLoop implements Runnable {
public void run(){
//Do stuff here
}
}
}
Instead of defining your class in your method body. Java variable names start with a lower case letter by convention. Comments start with // not \\. I think you wanted something like
public static void main(String[] args) {
Thread messageThread = new Thread(new MessageLoop());
messageThread.start();
}
static class MessageLoop implements Runnable {
public void run() {
// Do stuff here
}
}
Use following approaches.
Approach1
public static void main(String[] args) {
Thread MessageThread = new Thread(new MessageLoop());
MessageThread.start();
}
static class MessageLoop implements Runnable {
public void run(){
System.out.println("helllo");
}
}
Approach 2
public static void main(String[] args) {
Thread MessageThread2 = new Thread(new Runnable(){
public void run(){
System.out.println("helllo2");
}
});
MessageThread2.start();
}
I've write the following example:
public class MyThread extends Thread{
MyThread(Runnable r){
super(r);
}
public void run(){
System.out.println("run");
}
}
public static void main(String[] args)
{
Thread t = new MyThread(new Runnable() {
#Override
public void run() {
System.out.println("rrrrrrrrrruuuuuuuuuuuun");
}
});
t.start(); //run
}
Why does run methdo defined in MyThread was called instead?
Because the default behavior of a thread constructed with a Runnable is to delegate to the runnable passed as argument to the constructor. But you overrode run() in the thread itself, so instead of delegating to the runnable, it executes the code inside the overridden run() method.
For the record, here's the default implementation of Thread.run(), that you overrode:
private Runnable target;
public void run() {
if (target != null) {
target.run();
}
}
Because you the MyThread.run is not override, but the Runnable.run is. Now if you look at your implementation of MyThread.run, the stored Runnable plays no part in it. In other words, it doesn't matter what kind of runnable you give with the constructor. You should use:
public static void main(String[] args)
{
Thread t = new MyThread() {
#Override
public void run() {
System.out.println("rrrrrrrrrruuuuuuuuuuuun");
}
});
t.start(); //run
}
As #BorisTheSpider notes, overriding a Thread is in general not good practice: a Thread has the responsibility to start a Thread and give control to a runnable. A better implementation would be:
public static void main(String[] args)
{
Thread t = new Thread(new MyThread() {
#Override
public void run() {
System.out.println("rrrrrrrrrruuuuuuuuuuuun");
}
}));
t.start(); //run
}
I have a class like this , where I am updating a static variable in a thread. And I need to access this variable from another class.
import java.util.ArrayList;
import java.util.List;
public class VariableUpdater implements Runnable {
static List < String > abc = new ArrayList < String > ();
private static VariableUpdater instance = null;
private VariableUpdater() {}
public static synchronized VariableUpdater getInstance() {
if (instance == null) {
instance = new VariableUpdater();
}
return instance;
}
public static void main(String[] args) {
Thread th = new Thread( VariableUpdater.getInstance());
th.start();
}
#Override
public void run() {
while (true) {
System.out.println();
try {
abc.add("aa");
Thread.sleep(1000);
printContent();
} catch (Exception e) {
// TODO: handle exception
}
}
}
public synchronized void printContent() {
for (String string: abc) {
System.out.println(string);
}
}
}
And this variable needs to be accessed from another class like this :
public class Accessor {
public static void main(String[] args) {
VariableUpdater.getInstance().printContent();
}
}
The problem is, when running the Accessor class the list is empty.
Am I missing something here?
UPDATE/Solution
It turns out we can achieve this by using Hazelcast or some sort of messaging/caching utility. I will post a full solution soon.
Source: How to share object between java applications?
From this code u can access the List in another class object
import java.util.ArrayList;
import java.util.List;
public class VariableUpdater implements Runnable {
static List < String > abc = new ArrayList < String > ();
private static VariableUpdater instance = null;
private VariableUpdater() {}
public static synchronized VariableUpdater getInstance() {
if (instance == null) {
instance = new VariableUpdater();
}
return instance;
}
public static void main(String[] args) {
Thread th = new Thread(new VariableUpdater());
th.start();
Accessor.print();
}
#Override
public void run() {
for(int i=0;i<10;i++) {
System.out.println();
try {
abc.add("aa");
// Thread.sleep(1000);
//printContent();
} catch (Exception e) {
e.printStackTrace();
}
}
}
public synchronized void printContent() {
System.out.println("List :: " + abc);
}
}
class Accessor {
public static void print() {
System.out.println("Accessor");
VariableUpdater.getInstance().printContent();
}
}
You have two main() methods in two different classes. On running two main() methods there will be two instances of JVM and those do not share anything. So your list will always be empty.
Use one main() method to start threads.
public class Main{
//shared state
public static void main(String[] args){
VariableUpdator variableUpdatorInstance = ...
Accessor accessorInstance = ...
variableUpdatorInstance.start();
accessorInstance.start();
//or in your case
new Thread(new VariableUpdater()).start();
Thread.sleep(9000); //runs eventually after 9 seconds
Accessor.print();
}
}
UPDATE:
class Thread1 extends Thread{
static List<String> list = new ArrayList<String>();
}
class OtherClass{
public void someMethod(){
Thread1.list; //this is how you access static variable of one class in other
}
}
I have a main class which spawns a thread, let's call them MainClass and MyThread.
public class MainClass extends javax.swing.JFrame {
int sharedVariable;
MyThread threadInstance;
public MainClass (){
sharedVariable = 2;
threadInstance = new MyThread(this);
threadInstance.run();
}
public int getSharedVariable(){ return sharedVariable; }
public static void main(String[] args){
//begin main class
}
}
public class MyThread implements Runnable {
MainClass class;
public MyThread(MainClass main_class){
this.main_class= main_class;
}
#Override
public run(){
while(this.main_class is still active){
//grab status of sharedVariable and wait for x amount of time.
}
}
}
The problem is I do not know how to implement the while condition which checks if the MainClass instance is still alive and if it is, it has to use the this.main_class.getSharedVariable() to get the value of sharedVariable, then wait for x amount of time. MainClass has the main method .
I would recommend holding onto the Thread instance and then calling threadInstance.interrupt() right before the main(...) method exits.
Something like:
public static void main(String[] args){
MainClass mainClass = new MainClass();
try {
...
// do main stuff here
...
} finally {
mainClass.threadInstance.interrupt();
}
}
Then in your thread you'd do:
while(!Thread.currentThread().isInterrupted()){
...
}
You'd also want to handle InterruptedException correctly:
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// always a good pattern to re-interrupt the thread here
Thread.currentThread().interrupt();
// if we are interrupted quit
return;
}
Btw, it is very bad form to leak the instance of an object during construction to another thread:
new MyThread(this);
See here: Why shouldn't I use Thread.start() in the constructor of my class?
Also, you aren't starting a thread when you call threadInstance.run();. You are just running it in the current thread. You should use threadInstance.start() but not inside of the constructor like that.
You can use CountDownLatch which is very convenient for such tasks as waiting other threads to finish some activity (you can change Thread.sleep(...) argument in main to, say, 12000L and see what happens):
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
class OtherThread extends Thread {
private final CountDownLatch sharedLatch;
OtherThread(CountDownLatch sharedLatch) {
this.sharedLatch = sharedLatch;
}
#Override
public void run() {
boolean wokenByMain = false;
try {
wokenByMain = sharedLatch.await(10000L, TimeUnit.MILLISECONDS);
} catch (InterruptedException e) {
e.printStackTrace();
return; // or not return, whatever makes more sense in your case
}
System.out.println("heh: " + wokenByMain);
}
}
class SOSample {
public static void main(String[] args) throws InterruptedException {
CountDownLatch latch = new CountDownLatch(1);
OtherThread otherThread = new OtherThread(latch);
otherThread.start();
System.out.println("Scheduled other thread to be started");
Thread.sleep(1000L);
System.out.println("going to release other thread");
latch.countDown();
}
}
public class MainClass extends JFrame implements Runnable {
public static void main(String [] args) {
final Thread t=new Thread(new MainClass() {
public void run(){
//something
});
Thread t2=new Thread(new MyThread() {
public void run() {
while(t.isAlive) {
//something
}
}
});
}
}